Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
OpenGLCanvasBase.cpp
1 
2 /* author: Jan Woetzel */
3 
4 #include <Base/Common/BIASpragma.hh>
5 #include <Utils/GlutInitWrapper.hh>
6 #include "OpenGLCanvasBase.hh"
7 
8 //#if defined(wxUSE_GLCANVAS) && wxUSE_GLCANVAS
9 //# error + OK, wx compileed in gl configuration
10 //#else
11 //# error wx has not been compiled with wxUSE_GLCANVAS=1. Please set wx/setup.h wxUSE_GLCANVAS=1 and recompile WX.
12 //#endif
13 
14 
15 #include <Base/Image/ImageIO.hh>
16 #include <Base/Math/Vector2.hh>
17 #include <Base/Math/Vector3.hh>
18 #include <Base/Math/Vector4.hh>
19 #include <Base/Common/FileHandling.hh>
20 #include <Gui/StringConv.hh>
21 
22 // contains simple GL calls:
23 #include "GeometryGL.hh"
24 
25 // mode settings (vsync, multi sampling:
26 #include "SettingsGL.hh"
27 
28 
29 #include <string>
30 #include <sstream>
31 #include <iostream>
32 #include <fstream>
33 
34 
35 #include <wx/defs.h> // key code table
36 #include <wx/log.h>
37 
38 // Nvidia Stereo rendering conrol API:
39 #ifdef BIAS_HAVE_STEREOI
40 # include "StereoI.h"
41 #endif // BIAS_HAVE_STEREOI
42 
43 
44 // -----------------------------------------
45 using namespace std;
46 using namespace BIAS;
47 // -----------------------------------------
48 
49 // WARNING: if you change the event table here,
50 // you may need to change it in the derived classes, too! (jw)
51 BEGIN_EVENT_TABLE (OpenGLCanvasBase, wxGLCanvas)
52 EVT_PAINT (OpenGLCanvasBase::OnPaint)
53 EVT_SIZE (OpenGLCanvasBase::OnSize)
54 EVT_ERASE_BACKGROUND (OpenGLCanvasBase::OnEraseBackground)
55 EVT_CHAR (OpenGLCanvasBase::OnChar)
56 END_EVENT_TABLE()
57 
58 
59 // static initialization
60 unsigned int OpenGLCanvasBase::instancesTotalNo_ = 0;
61 double OpenGLCanvasBase::time = 0.0;
62 bool OpenGLCanvasBase::animationUpdateEnabled = OPENGLCANVASBASE_DEFAULT_animationUpdateEnabled;
63 
64 #ifdef BIAS_HAVE_STEREOI
65 // interface to nVidia consumer 3d stereo API
66 // Please use Get_pStereoAPI()
67 static StereoI* g_pStereoAPI = NULL;
68 #endif // BIAS_HAVE_STEREOI
69 
70 // ----------------------------------
71 
72 // -----------------------------------------
73 
74 
75 /// destructor
76 OpenGLCanvasBase::~OpenGLCanvasBase()
77 {
78 #ifdef BIAS_HAVE_FONTGL
79  delete p_font;
80  p_font=NULL;
81 #endif // BIAS_HAVE_FONTGL
82 }
83 
84 
85 OpenGLCanvasBase::OpenGLCanvasBase(
86  wxFrame* parent
87  ,wxWindowID id
88  ,const wxPoint& pos
89  ,const wxSize& size
90  ,long style
91  ,const wxString& name
92  ,int* attribList
93  ,const wxPalette& palette )
94  : wxGLCanvas(parent,id,pos,size,style,name,attribList,palette)
95  ,p_ownerframe(NULL)
96 #ifdef BIAS_HAVE_FONTGL
97  ,p_font(NULL)
98 #endif
99 {
100  //CALLINFO;
101 
102  instancesTotalNo_ ++;
103  InitMembers();
104  p_ownerframe=parent;
105 }
106 
107 
109  wxFrame* parent
110  ,wxGLContext* sharedContext
111  ,wxWindowID id
112  ,const wxPoint& pos
113  ,const wxSize& size
114  ,long style
115  ,const wxString& name
116  ,int* attribList
117  ,const wxPalette& palette )
118  : wxGLCanvas(parent,sharedContext,id,pos,size,style,name,attribList,palette)
119  ,p_ownerframe(NULL)
120 #ifdef BIAS_HAVE_FONTGL
121  ,p_font(NULL)
122 #endif
123 {
124  //CALLINFO;
125 
126  instancesTotalNo_ ++;
127  InitMembers();
128  p_ownerframe=parent;
129 }
130 
131 
133 {
134  //CALLINFO;
135 
137  InitWithContextDone_ = false;
138  framecount_ = 0;
139  animationUpdateEnabled = true;
140 }
141 
142 
144 {
145  if (InitWithContextDone_) return; /* already done */
146 
147  if (!GetContext())
148  {
149  BIASERR("skipped because GetContext failed on frame ");
150  return; // no context available
151  };
152  // OK so far
153  this->SetCurrent();
154 
155  if (!IsContextAvailable())
156  {
157  BIASERR("skipped because no context available on glGetString GL_VENDOR test");
158  return;
159  }
160 
161 
162 #if defined(BIAS_HAVE_GLUT)
163 # if defined(__FREEGLUT_H__) || defined(__FREEGLUT_STD_H__)
164  {
165  // freeglut really wants a glutInit call no matter if we use their renderarea handler or not.
166  int MyArgc=0;
167  BIAS::GlutInitWrapper::GetInstance()->Init( &MyArgc, (char**)NULL );
168  }
169 # endif
170 #endif
171 
172 
173 #if defined(BIAS_HAVE_GLEW)
174  /// OK, we have a (valid) Gl Context
175  /// run init with context once
176 # ifdef USE_EXPERIMENTAL_SETTING_GLEW
177  // some exp. beta drivers don't expose their "hidden" capabilities
178  // bypass extension query and force "on" for all extensions.
179  BIASERR("WARNING: you are forcing bypassing glew extension query"<<endl
180  <<"because USE_EXPERIMENTAL_SETTING_GLEW is defined."<<endl
181  <<"This is *NOT* recommended in general (JW)");
182  glewExperimental=GL_TRUE;
183 # endif // USE_EXPERIMENTAL_SETTING_GLEW
184  // init glew symbols:
185  int err = glewInit();
186  if (GLEW_OK != err) {
187  // problem: glewInit failed, something is seriously wrong
188  BIASERR("could not init GLEW. Error: "<<glewGetErrorString(err));
189  exit(-1);
190  };
191 #endif // BIAS_HAVE_GLEW
192 
193 
194 #if defined(WIN32) && defined(BIAS_HAVE_GLEW)
195  // vertical sync initialization
196  if (WGLEW_EXT_swap_control)
197  {
199  if (GetVSync()!=rendermode.vsync){
200  BIASERR("could not set vsync to "<<rendermode.vsync<<endl
201  <<"\tDoes the driver allow application controlled VSYNC/page swapping settings?"<<endl
202  <<"\tE.g. NVStereo will and driver tab may force overriding our settings." );
203  };
204  };
205 #endif // WIN32
206 
207 #ifdef BIAS_HAVE_FONTGL
208  if (p_font==NULL){
209  p_font=new DrawTextGL;
210  BIASASSERT(p_font!=NULL);
211 # ifdef WIN32
212  p_font->InitFont( GetDC(HWND(this->GetHandle())) );
213 # else // WIN32
214  p_font->InitFont( this->GetHandle() );
215 #endif // WIN32
216 
217  }
218 #endif // BIAS_HAVE_FONTGL
219 
220  InitWithContextDone_ =true;
221 }
222 
223 
225 {
226  CHECK_GL_ERROR;
227  if (!(GetParent()->IsShown())) {
228  //BIASERR("Parent not yet shown err1");
229  return false;
230  };
231  if (!GetContext()) {
232  BIASERR("Context not (yet?) available.");
233  return false; // no context available
234  }
235  CHECK_GL_ERROR;
236  if (!(GetParent()->IsShown())) return false;
237  // OK.
238 
239 #ifndef WIN32
240  // conflicts with FBO:
241  this->SetCurrent(); // get the GL rendering focus
242 #endif
243 
244  CHECK_GL_ERROR;
245  // get OpenGL info strings into std. strings:
246  const unsigned char * p_str=NULL;
247  p_str = glGetString(GL_VENDOR);
248  CHECK_GL_ERROR;
249  if ( p_str==NULL) {
250  BIASERR("No Context available (NULL ptr)");
251  CHECK_GL_ERROR;
252  return false;
253  };
254  return true; // OK.
255 }
256 
257 
259 {
260  BIASASSERT(p_ownerframe!=NULL);
261  return p_ownerframe;
262 }
263 
265 {
266  p_ownerframe=ptr;
267 }
268 
269 
270 /// return GL state info
271 void OpenGLCanvasBase::GetInfoGL(std::ostream & os)
272 {
273  if (!GetContext()) return; // no context available
274  this->SetCurrent(); // get the GL rendering focus
275  // identify current instance of this canvas (or derived class)
276  os<<"instance: "<<this->instance_<<endl;
277 
278  // display OpenGL status:
280  CHECK_GL_ERROR;
281 
282 #ifdef BIAS_HAVE_STEREOI
283  // display NV StereoI status:
284  this->StereoI_GetInfo(os);
285 #endif //BIAS_HAVE_STEREOI
286 }
287 
289  framecount_++;
290  wxGLCanvas::SwapBuffers();
291 }
292 
293 void
295 {
296  //CALLINFO;
297  CHECK_GL_ERROR;
298  // this routine is calling SetCurrent to get rendering focus:
299  if ( !IsContextAvailable() )
300  return;
301  if ( !InitWithContextDone_ )
302  InitWithContext();
303  if ( !InitWithContextDone_ )
304  return;
305 
306  if (!(GetParent()->IsShown())) {
307  BIASERR("Parent not yet shown.");
308  return;
309  };
310 
311  // realtime clock update (or specialized in derived classed)
312  UpdateTime(); //< only base needs this, the drived classes use OnIdle event to update the time.
313 
314  // dummy catching all previous uncaught GL errors (in particular of other applications)
315  glGetError();
316  CHECK_GL_ERROR;
317 
318  // display to correct buffer for stereo rendering:
320  CHECK_GL_ERROR;
321 
322  // set polygonmode, line+point size etc.
324  CHECK_GL_ERROR;
325  {
326  /// >>> begin your fancy GL calls (scene like)
327 
328  DisplayCalls();
329 
330  /// <<< end of your GL calls
331 
332  }
333  // check if we want to display FPS?
334  CHECK_GL_ERROR;
335 
336  this->SwapBuffers(); // glcanvas swap
337 }
338 
339 
341 {
342  /// >>> begin your fancy GL calls
343 
344  // simple sample calls:
345  this->DisplayClear();
346  this->DisplaySampleScene();
347 
348  /// <<< end of your GL calls
349 }
350 
351 
352 // useful only for quad buffered stereo:
354 {
355  CHECK_GL_ERROR;
356  // running quad buffered stereo?
357  static int bufferNr=0;
358  switch (rendermode.drawbuffermode)
359  {
360  case STEREO_UNTOUCHED:
361  break;
362  case MONO:
363  case STEREO_CONSUMER_NV:
364  glDrawBuffer(GL_BACK);
365  CHECK_GL_ERROR;
366  break;
367  case STEREO_LEFT_RIGHT:
368  {
369  // toggle between left and right:
370  if (bufferNr==0) {
371  glDrawBuffer(GL_LEFT);
372  CHECK_GL_ERROR;
373  bufferNr=1;
374  } else {
375  glDrawBuffer(GL_RIGHT);
376  CHECK_GL_ERROR;
377  bufferNr=0;
378  };
379  break;
380  }
381  case STEREO_QUADBUFFERED:
382  {
383  // supported by quadro cards:
384  //#ifdef BIAS_DEBUG
385  // cout<<endl<<"displaying quadbuffered /BACK_LEFT,BACK_RIGHT), bufferNr "<<bufferNr<<endl;
386  //#endif
387  // toggle between left and right:
388  if (bufferNr==0) {
389  glDrawBuffer(GL_BACK_LEFT);
390  CHECK_GL_ERROR;
391  bufferNr=1;
392  } else {
393  glDrawBuffer(GL_BACK_RIGHT);
394  CHECK_GL_ERROR;
395  bufferNr=0;
396  };
397  break;
398  };
399  default:
400  cout<<"unknown/unimplemented rendermode.stereomode"<<rendermode.drawbuffermode<<endl;
401  };
402  CHECK_GL_ERROR;
403 }
404 
405 
406 // static
407 void OpenGLCanvasBase::DisplayClear(const GLbitfield & mask)
408 {
410  CHECK_GL_ERROR;
411 }
412 
413 
415 {
417 }
418 
419 
420 //static
422 {
424 }
425 
426 // static
427 void OpenGLCanvasBase::DisplayCoordCross(const float & size, const float & linewidth)
428 {
429  GeometryGL::DisplayCoordCross(size, linewidth);
430 
431  // mark axes labels with "x,y,z"
432 #ifdef BIAS_HAVE_FONTGL
433  BIASASSERT(p_font!= NULL);
435  //GeometryGL::DisplayCoordCrossAxesLabel(size, *p_font
436  // ,"X axis"
437  // ,"Y axis"
438  // ,"Z axis"
439  // );
440 
441 #endif // BIAS_HAVE_FONTGL
442 }
443 
444 
446 {
447  // adapt the viewport to cover full window (overriden in child classes)
448  glViewport(0,0, GetWidth(), GetHeight() );
449 
450  // (re-)display on canvas decrease due to new viewport transformation
451  Display();
452 }
453 
454 
455 unsigned int OpenGLCanvasBase::GetWidth() const
456 {
457  int w, h;
458  //GetSize(&w, &h);
459  GetClientSize(&w, &h); // DBG
460  return w;
461 }
462 
463 
464 unsigned int OpenGLCanvasBase::GetHeight() const
465 {
466  int w, h;
467  //GetSize(&w, &h);
468  GetClientSize(&w, &h);
469  return h;
470 }
471 
472 
473 /// @return aspect 'X/Y' = ratio of width being 'bigger' than reference height
475  return ((float)GetWidth() / (float)GetHeight());
476 }
477 
478 
479 
482 {
484  if (!IsContextAvailable()) {
485  data.Set(0,0,0);
486  BIASERR("no context");
487  return data;
488  };
489  glReadPixels(
490  (GLint)pos2d.x,
491  (GLint)(GetHeight() -pos2d.y),
492  (GLsizei)1, (GLsizei)1,
493  GL_RGB,
494  GL_FLOAT,
495  (GLvoid*)(&data[0]) );
496  return data;
497 }
498 
499 
502 {
504  if (!IsContextAvailable()) {
505  data.Set(0,0,0,0);
506  BIASERR("no context");
507  return data;
508  };
509  glReadPixels((GLint)pos2d.x,
510  (GLint)(GetHeight() -pos2d.y),
511  (GLsizei)1, (GLsizei)1,
512  GL_RGBA,
513  GL_FLOAT,
514  (GLvoid*)(&data[0]) );
515  return data;
516 }
517 
518 
519 float
520 OpenGLCanvasBase::GetPixelValueDepth(const wxPoint & pos2d) const
521 {
522  float v=0.0;
523  CHECK_GL_ERROR
524  glReadPixels((GLint)pos2d.x,
525  (GLint)(GetHeight()-pos2d.y),
526  (GLsizei)1, (GLsizei)1,
527  GL_DEPTH_COMPONENT, /* GL_DEPTH */
528  GL_FLOAT,
529  (GLvoid*)&v );
530  CHECK_GL_ERROR
531  return v;
532 }
533 
534 
536 OpenGLCanvasBase::Unproject(const wxPoint & pos2d, double & d)
537 {
538  double pos3d[3];
539  GLint viewport[4];
540  GLdouble modelview[16];
541  GLdouble projection[16];
542  GLfloat wx=pos2d.x, wy=pos2d.y, wz=1;
543  GLint x=pos2d.x, y=pos2d.y; // non const version of pos2d
544 
545  glGetIntegerv(GL_VIEWPORT, viewport);
546  y=viewport[3]-y;
547  wy=y;
548  // get GL status matrices
549  glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
550  glGetDoublev(GL_PROJECTION_MATRIX, projection);
551 
552  // acces Z buffer value at (x,y)
553  glReadPixels(x, y, 1,1, GL_DEPTH_COMPONENT, GL_FLOAT, &wz);
554 
555  // compute 3D pos by "unprojection":
556  gluUnProject(wx,wy,wz,
557  modelview,
558  projection,
559  viewport,
560  &pos3d[0], &pos3d[1], &pos3d[2] );
561 
562  //COUT("DBG "<<" wx="<<wx<<" wy="<<wy<<" wz="<<wz" pos3d= "<<pos3d);
563 
564  d=wz;
565  //d=0; // TODO: not correctly implemented !
566 
567  // convert to float result:
568  BIAS::Vector3<float> result(pos3d[0], pos3d[1], pos3d[2] );
569  return result;
570 }
571 
572 
573 void OpenGLCanvasBase::ScreenShot(const std::string & filename,
574  const bool & flipY,
575  const GLenum & format,
576  const bool &force8Bit )
577 {
578  int nChannels=3;
579  if (format==GL_RGBA){
580  nChannels=4;
581  }
582 
583  // create a temporary CPU memory image, assume three channel RGB for now.
584  BIAS::ImageBase img(GetWidth(), GetHeight(), nChannels );
585 
586  this->ScreenShot(img, flipY, format, force8Bit);
587 
588  COUT("DBG "<<FUNCNAME<<" is writing "<<filename<<endl<<flush);
589  int result = BIAS::ImageIO::Save(filename, img );
590  if (result!=0)
591  {
592  BIASERR("could not save "<<filename<<" result="<<result );
593  }
594 }
595 
596 
597 
598 // JW
600  const bool & flipY,
601  const GLenum & format,
602  const bool &force8Bit )
603 {
604  // adapt image size to screen area:
605  // TODO: add similar "data area reesize really required" function to BIAS::Image
606 
607  unsigned int channels=3;
608  GLenum type = GL_UNSIGNED_BYTE;
609  unsigned int ByteDepth=1;
611 
612  switch (format)
613  {
614  case GL_DEPTH_COMPONENT:
615  if (!force8Bit)
616  {
617  // we need >=24 bits for depth maps (usually), so si use 32bit float
618  ByteDepth=4;
619  type=GL_FLOAT;
621  }
622  case GL_RED:
623  case GL_GREEN:
624  case GL_BLUE:
625  case GL_ALPHA:
626  case GL_LUMINANCE:
627  case GL_STENCIL_INDEX:
628  channels=1;
629  break;
630  case GL_LUMINANCE_ALPHA:
631  channels=2;
632  break;
633  case GL_RGB:
634  case GL_BGR_EXT:
635  channels=3;
636  break;
637  case GL_RGBA:
638  case GL_BGRA_EXT:
639  channels=4;
640  break;
641  default:
642  BIASERR("unsupported format");
643  }
644 
645  if ( (dest.GetWidth() != this->GetWidth())
646  || (dest.GetHeight() != this->GetHeight())
647  || (dest.GetChannelCount() != channels) /* nr. of channels */
648  || (dest.GetDepth() != ByteDepth) /* Byte per channel */
649  )
650  {
651  if (!dest.IsEmpty()) {
652  dest.Release();
653  };
654  dest.Init( this->GetWidth(), this->GetHeight(),
655  channels,
656  st,
657  true /*interleaved*/
658  );
659  }
660 
661  CHECK_GL_ERROR;
662 
663  // copy data from GPU to CPU:
664  // read a block from the framebuffer back to CPU
665 
666  //if (!IsContextAvailable()) {
667  // BIASERR("skipped screenshot because no context available.");
668  // return;
669  //}
670 
671  this->SetCurrent();
672  glFlush();
673  glFinish();
674  glReadPixels( GLint(0), GLint(0), // x,y from lower left
675  GLsizei(this->GetWidth()), GLsizei( this->GetHeight()), // width, height
676  format, // format,
677  type, //type
678  (GLvoid*)dest.GetImageData()
679  );
680  CHECK_GL_ERROR;
681 
682  // flip vertically because of different texcoord systems between OpenGL and MIP?
683  if (flipY) dest.Flip();
684 }
685 
686 // JW
688 {
689  static unsigned int savedNr=0;
690  // get context bits:
691  GLint red_bits=0;
692  GLint green_bits=0;
693  GLint blue_bits=0;
694  GLint alpha_bits=0;
695  GLint depth_bits=0;
696  GLint stencil_bits=0;
697  glGetIntegerv(GL_RED_BITS, &red_bits);
698  glGetIntegerv(GL_GREEN_BITS, &green_bits);
699  glGetIntegerv(GL_BLUE_BITS, &blue_bits);
700  glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
701  glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
702  glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
703 
704  // create unique filename
705  stringstream ss;
706  ss<<"out_screenshot_"
707  <<"savedNr"<<FileHandling::LeadingZeroString(savedNr,5)
708  <<"_framecount"<<FileHandling::LeadingZeroString(framecount_, 5)
710  ;
711 
712  // save RGB tetxure
713  if ((red_bits>0) || (green_bits>0) || (blue_bits>0)) {
714  this->ScreenShot( ss.str() +string("_RGB") +string(BIAS_SCREENSHOT_DEFAULT_EXTENSION),
715  true /*flip*/, GL_RGB );
716  }
717 
718  // save alpha map (if present)
719  if (alpha_bits>0){
720  this->ScreenShot( ss.str() +string("_ALPHA") +string(BIAS_SCREENSHOT_DEFAULT_EXTENSION),
721  true /*flip*/, GL_ALPHA );
722  }
723  // save combined rgba
724  if (red_bits>0 && green_bits>0 && blue_bits>0 && alpha_bits>0) {
725  this->ScreenShot( ss.str() +string("_RGBA") +string(BIAS_SCREENSHOT_DEFAULT_EXTENSION),
726  true /*flip*/, GL_RGBA );
727  }
728 
729 
730  // save depth map (if present)
731  if (depth_bits>0){
732  this->ScreenShot( ss.str() +string("_DEPTH") +string(BIAS_SCREENSHOT_DEFAULT_EXTENSION),
733  true /*flip*/, GL_DEPTH_COMPONENT );
734  }
735 
736  // save stencil buffer (if present)
737  if (stencil_bits>0){
738  this->ScreenShot( ss.str() +string("_STENCIL") +string(BIAS_SCREENSHOT_DEFAULT_EXTENSION),
739  true /*flip*/, GL_STENCIL_INDEX);
740  }
741 
742  savedNr++;
743 }
744 
745 
746 // JW
747 void OpenGLCanvasBase::SetStatusText(const wxString& text, int c_field )
748 {
749  bool statbarOK=false;
750  int field = c_field;
751 
752  if (p_ownerframe!=NULL){
753  if (p_ownerframe->GetStatusBar()!=NULL)
754  {
755  if (p_ownerframe->GetStatusBar()->GetFieldsCount()>field){
756  // everything is fine
757  statbarOK=true;
758  } else {
759  // status bar has not enough fields, disply to last field
760  //#ifdef BIAS_DEBUG
761  // BIASERR("p_ownerframe has no only "
762  // <<p_ownerframe->GetStatusBar()->GetFieldsCount()
763  // <<" fields. could not display to field="<<field<<"!");
764  //#endif // BIAS_DEBUG
765  field = (p_ownerframe->GetStatusBar()->GetFieldsCount()) -1;
766  statbarOK=true;
767  }
768  } else {
769  BIASERR("p_ownerframe has no status bar!");
770  }
771  //} else {
772  // BIASERR("p_ownerframe is NULL!");
773  };
774 
775  if (statbarOK)
776  {
777  p_ownerframe->SetStatusText(text, field);
778  } else {
779  // fallback output
780  cout<<field<<": "<<text<<endl;
781  };
782 }
783 
784 
785 void
786 OpenGLCanvasBase::ShowValue(const wxPoint & pos)
787 {
788  CHECK_GL_ERROR;
789  std::stringstream s;
790  double d=0.0;
791  BIAS::Vector3<float> p3d(0,0,0);
792  p3d = Unproject(pos, d);
793  CHECK_GL_ERROR;
794 
795  //get pixel value under mouse
796  BIAS::Vector4<float> rgbGL;
797  rgbGL = GetPixelValueRGBA(pos);
798  CHECK_GL_ERROR;
799  float depthGL= GetPixelValueDepth(pos);
800  CHECK_GL_ERROR;
801 
802  //s<<"2d: ";
803  s<<"("<<pos.x<<";"<<pos.y<<") ";
804  s<<"rgba=("
805  <<std::setprecision(5)<<rgbGL[0]<<";"
806  <<std::setprecision(5)<<rgbGL[1]<<";"
807  <<std::setprecision(5)<<rgbGL[2]<<";"
808  <<std::setprecision(5)<<rgbGL[3]<<") ";
809 
810  s<<"depthGL="<<std::setprecision(5)<<depthGL<<" ";
811 
812  s<<"3d: ";
813  s<<"["<<p3d[0]<<";"<<p3d[1]<<";"<<p3d[2]<<"] ";
814  s<<"dist. "<<d<<" ";
815 
816 //#ifdef BIAS_DEBUG
817 // // display in console (for debugging, in small windows)
818 // cout<<s.str()<<endl;
819 //#endif
820 
821  SetStatusText(AsciiToWx(s.str()));
822 }
823 
824 
825 // computes and displays current FPS in status bar
826 void OpenGLCanvasBase::ShowFPS(const int & framecounter,
827  const float & minUpdateIntervalSec,
828  const unsigned int & minNewFrames,
829  const unsigned int nField)
830 {
831  static float fps=0.0f;
832  static clock_t start=clock(); // init once
833  static unsigned int startFrameNo = framecounter;
834 
835  // how many frames were drawn since last call:
836  unsigned int nNewFrames = framecounter - startFrameNo;
837  if (nNewFrames==0) {
838  // no frames rendered, keep old value, do not update status bar
839  return;
840  } else if (nNewFrames<minNewFrames) {
841  // too few frames for reliable measurement, keep old, do not update status bar
842  return;
843  };
844 
845  // measure time and fps since last fps display
846  clock_t stop=clock();
847  clock_t duration = stop -start;
848 
849  if (float(duration)==0){
850  // do nothing, keep old value
851  return;
852  } else if (duration>=float(CLOCKS_PER_SEC)*minUpdateIntervalSec){
853  //
854  // OK
855  //
856 
857  // compute avg fps of the last nNewFrames images
858  fps = (float)nNewFrames * float(CLOCKS_PER_SEC)/(float)duration;
859 
860  //
861  // prepare next measurement
862  //
863  // next start is this stop
864  start=stop;
865  startFrameNo = framecounter;
866 
867  //
868  // update status bar
869  //
870  stringstream ss;
871  ss<<fps<<" fps "
872  <<"("<<framecounter<<")."
873  ;
874  SetStatusText(AsciiToWx(ss.str()), nField);
875  };
876 }
877 
878 
879 
880 // HACK: doing fullscreen on frame instead of canvas for now. (JW)
881 // TODO: hide this, create frame directly around canvas, fullscreen
883 {
884  if (p_ownerframe!=NULL) {
885  long style=0;
887  // works only in true fullscreen,
888  // thus all menu and statusbar need to be disabled!
889  style = style | wxFULLSCREEN_ALL;
890  }
891  p_ownerframe->ShowFullScreen(
892  !(p_ownerframe->IsFullScreen()),
893  style
894  |OpenGLCanvasBase_DEFAULT_FULLSCREEN_STYLE
895  //|wxFULLSCREEN_NOMENUBAR
896  //|wxFULLSCREEN_NOTOOLBAR
897  //|wxFULLSCREEN_NOSTATUSBAR
898  //|wxFULLSCREEN_NOBORDER
899  //|wxFULLSCREEN_NOCAPTION
900  //|wxFULLSCREEN_ALL
901  );
902  }
903 }
904 
905 
907 {
908  ShowFPS(this->framecount_,
909  3.0f, /* sec, */
910  1, /* nr of new frames */
911  1 /* nField in status bar */
912  );
913 }
914 
915 
916 ///
917 /// EVT handlers: ------------------------------------------
918 ///
919 
920 void OpenGLCanvasBase::OnPaint( wxPaintEvent &WXUNUSED(event) )
921 {
922  // This is a dummy, to avoid an endless succession of paint messages.
923  // OnPaint handlers must always create a wxPaintDC.
924  wxPaintDC dc(this);
925  Display();
926 }
927 
928 
929 void OpenGLCanvasBase::OnSize(wxSizeEvent& )
930 {
931  Reshape();
932 }
933 
934 
935 std::ostream & OpenGLCanvasBase::PrintHelp(std::ostream & os)
936 {
937  os<<"key function assignment:"<<endl
938  <<"F1\t this help"<<endl
939  <<"F10, INSERT, p\t Screenshot"<<endl
940  <<"z,y\tPOINT rendering mode"<<endl
941  <<"x\tLINE polygon rendering mode (wireframe)"<<endl
942  <<"c\tFILL polygon rendering mode (vertices)"<<endl
943  <<"v\tFILL front, LINE back polygon rendering mode"<<endl
944  <<"Z,Y\tSMOOTH shading mode"<<endl
945  <<"X\tFLAT shading mode"<<endl
946  <<"i\tInformation, e.g. on OpenGL status"<<endl
947  <<"k\t toggle culling back sides"<<endl
948  <<"K\t toggle culling front sides"<<endl
949  <<"L\t toggle culling front and back sides, "<<endl
950  <<" \t =draw only LINES and POINTS, no faces at all."<<endl
951  <<"]\t increase pointsize (++)"<<endl
952  <<"[\t decrease pointsize (--)"<<endl
953  <<"s\tstop animation (halt)"<<endl
954  <<"a\tanimate=run animation"<<endl
955  <<"f,F\ttoggle Fullscreen modus (of the frame)"<<endl
956  <<"V\ttoggle VSYNC swap control on/off"<<endl
957  ;
958  return os;
959 }
960 
961 
962 //JW
963 void OpenGLCanvasBase::OnChar(wxKeyEvent& event)
964 {
965  switch (event.GetKeyCode())
966  {
967  case WXK_F1: /* popup simple help */
968  {
969  stringstream ss;
970  PrintHelp(ss);
971  ::wxMessageBox(AsciiToWx(ss.str()), wxT("Help"), wxICON_INFORMATION | wxOK );
972  break;
973  }
974 #ifdef BIAS_HAVE_STEREOI
975  case WXK_F3:
976  //StereoI_Init();
977  StereoI_GetInfo();
978  break;
979 #endif // BIAS_HAVE_STEREOI
980  case WXK_PRINT: /* is ignored on WinXP, thus assign other keys, too. (jw) */
981  case 'p':
982  case WXK_F10:
983  SetStatusText(wxT("saving screenshot."));
984  this->ScreenShot(); break;
985  //case WXK_F5: // toggles idleRepaintEnabled
986  // {
987  // idleRepaintEnabled = !idleRepaintEnabled ;
988  // stringstream ss;
989  // ss<<"Toggled idleRepaintEnabled="<<idleRepaintEnabled;
990  // // TODO: Disconnect, GetEventHandler
991  // this->GetEventHandler()->Disconnect( ID, wxID_ANY, EVT_IDLE);
992  // cout<<ss.str()<<endl;
993  // SetStatusText( ss.str().c_str() );
994  // break;
995  // }
996  case 'z': /* english keyboard */
997  case 'y': /* german keyboard */
998  rendermode.polygonmodeFRONT=GL_POINT;
999  rendermode.polygonmodeBACK=GL_POINT;
1000  SetStatusText(wxT("PolygonMode POINT"));
1001  Display();
1002  break;
1003  case 'x': /* wireframe */
1004  rendermode.polygonmodeFRONT=GL_LINE;
1005  rendermode.polygonmodeBACK=GL_LINE;
1006  SetStatusText(wxT("PolygonMode LINE"));
1007  Display();
1008  break;
1009  case 'c':
1010  rendermode.polygonmodeFRONT=GL_FILL;
1011  rendermode.polygonmodeBACK=GL_FILL;
1012  SetStatusText(wxT("PolygonMode FILL"));
1013  Display();
1014  break;
1015  case 'v':
1016  // useful to debug culling
1017  rendermode.polygonmodeFRONT=GL_FILL;
1018  rendermode.polygonmodeBACK=GL_LINE;
1019  SetStatusText(wxT("PolygonMode: front=FILL, back=LINE"));
1020  Display();
1021  break;
1022  case 'Z':
1023  case 'Y':
1024  rendermode.shademodel=GL_SMOOTH;
1025  SetStatusText(wxT("SMOOTH shading"));
1026  Display();
1027  break;
1028  case 'X':
1029  rendermode.shademodel=GL_FLAT;
1030  SetStatusText(wxT("FLAT shading"));
1031  Display();
1032  break;
1033  case 'k':
1034  // backface culling = right hand order to viewer is drawn
1035  if (rendermode.cullface==GL_BACK)
1037  else
1038  rendermode.enable_cullface = true;
1039  rendermode.cullface=GL_BACK;
1041  SetStatusText(wxT("enabled culling BACK sides (clockwise ordering) "));
1042  else
1043  SetStatusText(wxT("disabled culling."));
1044  Display();
1045  break;
1046  case 'K':
1047  if (rendermode.cullface==GL_FRONT)
1049  else
1050  rendermode.enable_cullface = true;
1051  rendermode.cullface=GL_FRONT;
1053  SetStatusText(wxT("enabled culling FRONT sides (counterclockwise ordering) "));
1054  else
1055  SetStatusText(wxT("disabled culling. "));
1056  Display();
1057  break;
1058  case 'L':
1059  if (rendermode.cullface==GL_FRONT_AND_BACK)
1061  else
1062  rendermode.enable_cullface = true;
1063  rendermode.cullface=GL_FRONT_AND_BACK;
1064  // unusual: culling all faces, only lines and points ar drawn!
1066  SetStatusText(wxT("warning: Culling front and back. No faces are drawn, only LINES and POINTS are drawn, no polygones!"));
1067  else
1068  SetStatusText(wxT("disabled culling."));
1069  Display();
1070  break;
1071  case 'i': /* show information */
1072  {
1073  stringstream ss;
1074  this->GetInfoGL(ss);
1075  cout<<ss.str()<<endl;
1076  // this window is too big, add wxDialog with scrollable text control
1077  //::wxMessageBox(wxString(ss.str().c_str()), "Information", wxICON_INFORMATION | wxOK );
1078  ::wxMessageBox(wxT("see cout for information on current OpenGL status."), wxT("Information"), wxICON_INFORMATION | wxOK );
1079  break;
1080  }
1081  case ']':
1082  {
1084  BIASASSERT(rendermode.pointsize>=1.0f);
1085  BIASASSERT(rendermode.pointsize<=63.0f);
1086  stringstream ss;
1087  ss<<"increased pointsize to "<<rendermode.pointsize;
1088  SetStatusText( AsciiToWx(ss.str()) );
1089  Display();
1090  break;
1091  }
1092  case '[':
1093  {
1094  if (rendermode.pointsize>1.0f) {
1096  }
1097  BIASASSERT(rendermode.pointsize>=1.0f);
1098  BIASASSERT(rendermode.pointsize<=63.0f);
1099  stringstream ss;
1100  ss<<"decreased pointsize to "<<rendermode.pointsize;
1101  SetStatusText( AsciiToWx(ss.str()) );
1102  Display();
1103  break;
1104  }
1105  case 's':
1106  animationUpdateEnabled =false;
1107  SetStatusText(wxT("stopped animation")); break;
1108  case 'a':
1109  animationUpdateEnabled = true;
1110  SetStatusText(wxT("animation running")); break;
1111  case 'f':
1112  case 'F':
1113  ToggleFullScreen(); break;
1114  case 'V':
1115  {
1116  string msg;
1117  if (!ToggleVSync()){
1118  // error
1119  msg="toggling failed. still: ";
1120  BIASERR("toggling VSync failed. Please verify: "<<endl
1121  <<" -application controlled vsync should be set in driver tab on WIN32"<<endl
1122  <<" -Nvidia Stereo driver may override vsync (for shutter glasses)"<<endl );
1123  }
1124  if (GetVSync())
1125  msg+="VSYNC enabled";
1126  else
1127  msg+="VSYNC disable";
1128  COUT(msg<<endl);
1129  SetStatusText(AsciiToWx(msg));
1130  break;
1131  }
1132  }; // end of switch keycode
1133  // always skip keycodes because parent canvases may use them, too - e.g. for menu short cuts.
1134  event.Skip();
1135 }
1136 
1137 
1139 {
1140  // do nothing (with intention) to help avoid flashing
1141 }
1142 
1143 
1144 void OpenGLCanvasBase::SetVSync( const bool & trueForOn )
1145 {
1146  if (trueForOn)
1147  SettingsGL::SetVSyncInterval( int(1) );
1148  else
1149  SettingsGL::SetVSyncInterval( int(0) );
1150 }
1151 
1152 
1154 {
1155  return (SettingsGL::GetVSyncInterval() != int(0) );
1156 }
1157 
1158 
1160 {
1161  bool act = GetVSync();
1162  SetVSync( !act ); // try to toggle
1163  // did the status really change?
1164  return (act!= GetVSync() );
1165 }
1166 
1167 
1169 {
1170  time = double(clock()) / double(CLOCKS_PER_SEC);
1171 }
1172 
1173 bool OpenGLCanvasBase::ToggleIP(bool & value){
1174  value = !value;
1175  return value;
1176 }
1177 
1178 
1179 // JW
1180 #ifdef BIAS_HAVE_STEREOI
1182 {
1183  if (g_pStereoAPI!=NULL){
1184  BIASERR("StereoI API already initialized through g_pStereoAPI."<<endl
1185  <<"\tinterface creation should be called once, only. aborting." );
1186  return -1;
1187  };
1188  // must be NULL to use interface only once.
1189  BIASASSERT(g_pStereoAPI==NULL);
1190  if(!CreateStereoI(&g_pStereoAPI)){
1191  BIASERR("CreateStereoI failed. Did you install NVStereo and Nvidia GPU drivers? aborting.");
1192  g_pStereoAPI = NULL;
1193  return -2;
1194  };
1195  BIASASSERT(g_pStereoAPI!=NULL);
1196  if (g_pStereoAPI->GetStereoState() == STEREO_STATE_DISABLED){
1197  BIASERR("Stereo is currently DISABLED. Did you install enable NVStereo in the driver control panel?");
1198  return -3;
1199  }
1200 
1201  // be verbose on current status:
1202  StereoI_GetInfo();
1203 
1204  return 0; // OK=success
1205 }
1206 
1207 
1208 /* catch missing initializations
1209 and insert assertion on NULL ptr */
1210 StereoI* Get_pStereoAPI(){
1211  if (g_pStereoAPI==NULL)
1213  if (g_pStereoAPI==NULL){
1214  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1215  return NULL;
1216  }
1217  BIASASSERT(g_pStereoAPI!=NULL);
1218  return g_pStereoAPI;
1219 }
1220 
1221 
1223 {
1224  if (Get_pStereoAPI()==NULL)
1225  {
1226  StereoI_Init();
1227  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1228  return;
1229  }
1230  os<<"*StereoI state is:"<<endl;
1231  int tmp=0;
1232  os<<"CheckAPIVersion >=1: "<<bool(Get_pStereoAPI()->CheckAPIVersion(1)>=0)<<endl;
1233 
1234  tmp=Get_pStereoAPI()->GetStereoState();
1235  switch (tmp){
1236  case STEREO_STATE_ENABLED:
1237  os<<"STEREO_STATE_ENABLED"<<endl;
1238  break;
1239  case STEREO_STATE_DISABLED:
1240  os<<"STEREO_STATE_DISABLED"<<endl;
1241  default:
1242  {
1243  stringstream ss;
1244  ss<<"STEREO_STATE="<<tmp<<" is unknown.";
1245  BIASERR(ss.str());
1246  break;
1247  }
1248  };
1249  os<<"Separation: "<<Get_pStereoAPI()->GetSeparation()<<endl;
1250  os<<"Convergence: "<<Get_pStereoAPI()->GetConvergence()<<endl;
1251 }
1252 
1253 
1254 // simple wrappers:
1256 {
1257  if (Get_pStereoAPI()==NULL) {
1258  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1259  return 0.0f;
1260  }
1261  return Get_pStereoAPI()->GetStereoState();
1262 }
1264 {
1265  if (Get_pStereoAPI()==NULL) {
1266  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1267  return 0.0f;
1268  }
1269  return Get_pStereoAPI()->SetStereoState(val);
1270 }
1272 {
1273  if (Get_pStereoAPI()==NULL) {
1274  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1275  return 0.0f;
1276  }
1277  return Get_pStereoAPI()->GetSeparation();
1278 }
1280 {
1281  if (Get_pStereoAPI()==NULL) {
1282  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1283  return 0.0f;
1284  }
1285  return Get_pStereoAPI()->SetSeparation(val);
1286 }
1288 {
1289  if (Get_pStereoAPI()==NULL) {
1290  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1291  return 0.0f;
1292  }
1293  return Get_pStereoAPI()->GetConvergence();
1294 }
1296 {
1297  if (Get_pStereoAPI()==NULL) {
1298  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1299  return 0.0f;
1300  }
1301  return Get_pStereoAPI()->SetConvergence(val);
1302 }
1304  const int & quality)
1305 {
1306  if (Get_pStereoAPI()==NULL) {
1307  BIASERR("StereoI API not avaible through g_pStereoAPI.");
1308  return;
1309  }
1310  return Get_pStereoAPI()->CaptureStereoImage(format, quality);
1311 }
1312 #endif // BIAS_HAVE_STEREOI
1313 
1314 
1315 
static float StereoI_SetConvergence(const float &val)
virtual void DisplayRenderMode()
display default shade model, polygon mode,
BIAS::Vector3< float > GetPixelValueRGB(const wxPoint &pos2d)
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this-&gt;data_
Definition: Vector3.hh:532
virtual void GetInfoGL(std::ostream &os)
return GL state information
static float StereoI_GetSeparation()
static void StereoI_GetInfo(std::ostream &os=std::cout)
query status information on current NVStereo rendering state JW
static bool animationUpdateEnabled
unsigned int GetDepth() const
returns the bytes per channel, which is the sizeof(StorageType) Should match GetSizeDepth(GetStorageT...
Definition: ImageBase.hh:328
wxString AsciiToWx(const char *thestring)
Converts a C string to a wxString.
Definition: StringConv.hh:32
static int StereoI_GetStereoState()
wrappers for StereoI interface
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
virtual void InitMembers()
any constructor should call this function to initialize all data members (e.g.
static void DisplayCoordCross(const float &size=1.0f, const float &linewidth=1.0f)
draw a coord cross as three lines in r,g,b
Definition: GeometryGL.cpp:598
virtual void OnChar(wxKeyEvent &event)
void SwapBuffers()
expands parents SwapBUffers by automatic framecount increase
static void GetInfoGL(std::ostream &os)
print all GL state informatino to os including displaylist, texobj and matric info ...
Definition: GeometryGL.cpp:411
static int StereoI_SetStereoState(const int &val)
static void DisplayRenderMode(const BIAS::RenderModeGL &m)
Definition: GeometryGL.cpp:478
bool IsContextAvailable()
activates the current rendereing context if there is one and
static int GetVSyncInterval()
query status of vsync/swap control interval=VSYNC JW
Definition: SettingsGL.cpp:60
float image storage type
Definition: ImageBase.hh:118
void Set(const T &scalar)
set all elements to a scalat value
Definition: Vector4.hh:421
void ScreenShot()
JW automatic screenshot to file with filename based on frame, instance etc.
BIAS::RenderModeGL rendermode
GLenum cullface
glCullFace: GL_FRONT, GL_BACK, and GL_FRONT_AND_BACK
Definition: RenderModeGL.hh:83
void OnSize(wxSizeEvent &event)
static void DisplayClear(const GLbitfield &mask=CLEAR_DEFAULT_MASK)
utility functions
Definition: GeometryGL.cpp:424
void OnEraseBackground(wxEraseEvent &event)
void DisplaySelectBuffer()
useful for quadbuffered stereo, e.g. shutetr glasses
float GetPixelValueDepth(const wxPoint &pos2d) const
unsigned int GetWidth() const
Definition: ImageBase.hh:312
BIAS::Vector3< float > Unproject(const wxPoint &pos2d, double &d)
computes 3D coordinate from 2D+Z by &quot;unprojection&quot; JW
void ShowFPS()
simple interface for the above
static int StereoI_Init()
interace to NVidias consumer Stereo NVStereo driver API.
int InitFont(void *handleDC, const std::string theFontname=std::string(DrawTextGL_DEFAULT_FONTNAME), const int fontHeight=DrawTextGL_DEFAULT_FONTSIZE)
set the font up
Definition: DrawTextGL.cpp:80
static bool ToggleVSync()
try to toggle VSync setting.
unsigned int GetHeight() const
GLenum polygonmodeBACK
glPoygonMode(GL_BACK...
Definition: RenderModeGL.hh:77
const void * GetImageData() const
Definition: ImageBase.hh:280
static void StereoI_CaptureStereoImage(const int &format, const int &quality)
virtual void InitWithContext()
init all things that need a context.
void DisplayCoordCross(const float &size=1.0f, const float &linewidth=1.0f)
GLenum shademodel
glShadeModel(...
Definition: RenderModeGL.hh:80
static unsigned int instancesTotalNo_
static GlutInitWrapper * GetInstance()
base class for OpenGL canvases you could derive from to get base functionality (JW) ...
GLenum polygonmodeFRONT
glPoygonMode(GL_FRONT...
Definition: RenderModeGL.hh:71
unsigned int GetWidth() const
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
BIAS::DrawTextGL * p_font
static std::string LeadingZeroString(const int &n, const unsigned int &digits=DEFAULT_LEADING_ZEROS)
Create a string with leading zeroes from number.
float GetAspectRatio() const
GetAspectRatio is X/Y.
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void SetOwnerframe(wxFrame *ptr)
static bool ToggleIP(bool &value)
helper toggling a bool value in place
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
static void SetVSyncInterval(const int &interval)
set the vsync/swap control interval JW
Definition: SettingsGL.cpp:27
void SetStatusText(const wxString &text, const int c_field=0)
let an OpenGL canvas use the status bar of the containing frame and cout as fallback (JW) ...
void Release(const bool reset_storage_type=false)
Free the allocated data structures Hands off: Do !!NOT!! change the default of reset_storage_type: Im...
Definition: ImageBase.cpp:350
virtual std::ostream & PrintHelp(std::ostream &os)
pop up keyboard layout help.
void ShowValue(const wxPoint &pos)
void Init(unsigned int width, unsigned int height, unsigned int nChannels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
Initialize image size and channels.
Definition: ImageBase.cpp:229
static void DisplaySceneExampleSimple()
Definition: GeometryGL.cpp:517
BIAS::Vector4< float > GetPixelValueRGBA(const wxPoint &pos2d)
(8bit) unsigned char image storage type
Definition: ImageBase.hh:112
static float StereoI_GetConvergence()
static void DisplayCoordCrossAxesLabel(const float &size, const BIAS::DrawTextGL &font, const std::string &LabelX=std::string("x"), const std::string &LabelY=std::string("y"), const std::string &LabelZ=std::string("z"))
draw only the axes labels for a coord cross as text in r,g,b JW
Definition: GeometryGL.cpp:568
static void DisplaySampleScene()
display soem very simple Gl calls to draw something at all
virtual void Reshape()
change of size and aspect ratio.
int Flip()
flips the image vertically (row order is inverted) In place function return 0 in case of success...
Definition: ImageBase.cpp:834
static float StereoI_SetSeparation(const float &val)
BIAS::DrawbufferMode drawbuffermode
Definition: RenderModeGL.hh:89
virtual void UpdateTime()
sets the internal time param, by default based on realtime wall clock
virtual void DisplayClear(const GLbitfield &mask=CLEAR_DEFAULT_MASK)
clears buffers and resets virtual camera to identity
void OnPaint(wxPaintEvent &event)
EVT handlers: ---------------------------------------—.
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
OpenGLCanvasBase(wxFrame *parent, wxWindowID id=-1, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0, const wxString &name=AsciiToWx("OpenGLCanvasBase"), int *attribList=NULL, const wxPalette &palette=wxNullPalette)
static void SetVSync(const bool &trueForOn)
vertical sync control on or off (VSYNC) JW
Draw text to OpenGL as 2D bitmap font.
Definition: DrawTextGL.hh:71
virtual void Display()
main display call to be overridden by child classes usually displays: -InitWithContext (must be done ...