GLRenderer.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00023 #include <wx/wx.h>
00024 #include <wx/platform.h>
00025 
00026 #ifdef __WXMAC__
00027 #include <OpenGL/gl.h>
00028 #include <OpenGL/glu.h>
00029 #else
00030 #ifdef __WXMSW__
00031 #include <vigra/windows.h>
00032 #endif
00033 #include <GL/gl.h>
00034 #include <GL/glut.h>
00035 
00036 #endif
00037 
00038 #include <config.h>
00039 
00040 #include "panoinc.h"
00041 
00042 #include "TextureManager.h"
00043 #include "MeshManager.h"
00044 #include "ViewState.h"
00045 #include "GLRenderer.h"
00046 #include "ToolHelper.h"
00047 #include <panodata/PanoramaOptions.h>
00048 
00049 GLRenderer::GLRenderer(const wxColour backgroundColour)
00050 {
00051     m_background_color = backgroundColour;
00052 };
00053 
00054 void GLRenderer::SetPreviewBackgroundColor(const wxColour c)
00055 {
00056     m_background_color = c;
00057 }
00058 
00059 void GLRenderer::SetBackground(unsigned char red, unsigned char green, unsigned char blue)
00060 {
00061     glClearColor((float) red / 255.0, (float) green / 255.0, (float) blue / 255.0, 1.0);
00062 }
00063 
00064 GLRenderer::~GLRenderer()
00065 {
00066 }
00067 
00068 GLPreviewRenderer::GLPreviewRenderer(PT::Panorama *pano, TextureManager *tex_man,
00069                        MeshManager *mesh_man, VisualizationState *visualization_state,
00070                        PreviewToolHelper *tool_helper,const wxColour backgroundColour) : GLRenderer(backgroundColour)
00071 {
00072     m_pano = pano;
00073     m_tex_man = tex_man;
00074     m_mesh_man = mesh_man;
00075     m_visualization_state = visualization_state;
00076     m_tool_helper = tool_helper;
00077 }
00078 
00079 GLPanosphereOverviewRenderer::GLPanosphereOverviewRenderer(PT::Panorama *pano, TextureManager *tex_man,
00080                        MeshManager *mesh_man, PanosphereOverviewVisualizationState *visualization_state,
00081                        PanosphereOverviewToolHelper *tool_helper, const wxColour backgroundColour) : GLRenderer(backgroundColour)
00082 {
00083     m_pano = pano;
00084     m_tex_man = tex_man;
00085     m_mesh_man = mesh_man;
00086     m_visualization_state = visualization_state;
00087     m_tool_helper = tool_helper;
00088 }
00089 
00090 GLPlaneOverviewRenderer::GLPlaneOverviewRenderer(PT::Panorama *pano, TextureManager *tex_man,
00091                        MeshManager *mesh_man, PlaneOverviewVisualizationState *visualization_state,
00092                        PlaneOverviewToolHelper *tool_helper, const wxColour backgroundColour) : GLRenderer(backgroundColour)
00093 {
00094 
00095     m_pano = pano;
00096     m_tex_man = tex_man;
00097     m_mesh_man = mesh_man;
00098     m_visualization_state = visualization_state;
00099     m_tool_helper = tool_helper;
00100 }
00101 
00102 vigra::Diff2D GLPreviewRenderer::Resize(int in_width, int in_height)
00103 {
00104   width = in_width;
00105   height = in_height;
00106   glViewport(0, 0, width, height);
00107   // we use the view_state rather than the panorama to allow interactivity.
00108   HuginBase::PanoramaOptions *options = m_visualization_state->getViewState()->GetOptions();
00109   width_o = options->getWidth();
00110   height_o = options->getHeight();
00111   double aspect_screen = double(width) / double (height),
00112         aspect_pano = width_o / height_o;
00113   glMatrixMode(GL_PROJECTION);
00114   glLoadIdentity();  
00115   double scale;
00116   if (aspect_screen < aspect_pano)
00117   {
00118       // the panorama is wider than the screen
00119       scale = width_o / width;
00120   } else {
00121       // the screen is wider than the panorama
00122       scale = height_o / height;
00123   }
00124   double x_offs = (scale * double(width) - width_o) / 2.0,
00125          y_offs = (scale * double(height) - height_o) / 2.0;
00126   // set up the projection, so we can use panorama coordinates.
00127   glOrtho(-x_offs, width * scale - x_offs,
00128           height * scale - y_offs, -y_offs,
00129           -1.0, 1.0);
00130   // scissor to the panorama.
00131   glScissor(x_offs / scale, y_offs / scale,
00132             width_o / scale, height_o / scale);
00133   glMatrixMode(GL_MODELVIEW);
00134   // tell the view state the region we are displaying.
00135   // TODO add support for zooming and panning.
00136   m_visualization_state->SetVisibleArea(vigra::Rect2D(0, 0, options->getWidth(),
00137                                              options->getHeight()));
00138   m_visualization_state->SetScale(1.0 / scale);
00139 
00140   // return the offset from the top left corner of the viewpoer to the top left
00141   // corner of the panorama.
00142   return vigra::Diff2D(int (x_offs / scale), int (y_offs / scale));
00143 }
00144 
00145 void GLPreviewRenderer::Redraw()
00146 {
00147     glClear(GL_COLOR_BUFFER_BIT);
00148     glEnable(GL_SCISSOR_TEST);
00149     m_tex_man->DisableTexture();
00150     // background color of flat pano preview
00151     glColor3f((float)m_background_color.Red()/255, (float)m_background_color.Green()/255, (float)m_background_color.Blue()/255);
00152     glBegin(GL_QUADS);
00153         glVertex2f(0.0, 0.0);
00154         glVertex2f(width_o, 0.0);
00155         glVertex2f(width_o, height_o);
00156         glVertex2f(0.0, height_o);
00157     glEnd();
00158     glColor3f(1.0, 1.0, 1.0);
00159     // draw things under the preview images
00160     // draw each active image.
00161     int imgs = m_pano->getNrOfImages();
00162     // offset by a half a pixel
00163     glPushMatrix();
00164     glTranslatef(0.5, 0.5, 0.0);
00165     glEnable(GL_TEXTURE_2D);
00166     m_tex_man->Begin();
00167     m_tool_helper->BeforeDrawImages();
00168     // The old preview shows the lowest numbered image on top, so do the same:
00169     for (int img = imgs - 1; img != -1; img--)
00170     {
00171         // only draw active images
00172         if (m_pano->getImage(img).getActive())
00173         {
00174             // the tools can cancel drawing of images.
00175             if (m_tool_helper->BeforeDrawImageNumber(img))
00176             {
00177                 // the texture manager may need to call the display list
00178                 // multiple times with blending, so we pass it the display list
00179                 // rather than switching to the texture and then calling the
00180                 // list ourselves.
00181                 m_tex_man->DrawImage(img, m_mesh_man->GetDisplayList(img));
00182                 m_tool_helper->AfterDrawImageNumber(img);
00183             }
00184         }
00185     }
00186     m_tex_man->End();
00187     // drawn things after the active image.
00188     m_tool_helper->AfterDrawImages();
00189     m_tex_man->DisableTexture();
00190     glPopMatrix();
00191     // darken the cropped out range
00192     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00193     glEnable(GL_BLEND);
00194     glColor4f(0.0, 0.0, 0.0, 0.5);
00195     // construct a strip of quads, with each pair being one of the corners.
00196     const vigra::Rect2D roi = m_visualization_state->getViewState()->GetOptions()->getROI();
00197     glBegin(GL_QUAD_STRIP);
00198         glVertex2f(0.0,     0.0);      glVertex2i(roi.left(),  roi.top());
00199         glVertex2f(width_o, 0.0);      glVertex2i(roi.right(), roi.top());
00200         glVertex2f(width_o, height_o); glVertex2i(roi.right(), roi.bottom());
00201         glVertex2f(0.0,     height_o); glVertex2i(roi.left(),  roi.bottom());
00202         glVertex2f(0.0,     0.0);      glVertex2i(roi.left(),  roi.top());
00203     glEnd();
00204     // draw lines around cropped area.
00205     // we want to invert the color to make it stand out.
00206     glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
00207     glColor3f(1.0, 1.0, 1.0);
00208     glBegin(GL_LINE_LOOP);
00209         glVertex2i(roi.left(),  roi.top());
00210         glVertex2i(roi.right(), roi.top());
00211         glVertex2i(roi.right(), roi.bottom());
00212         glVertex2i(roi.left(),  roi.bottom());
00213     glEnd();
00214     glDisable(GL_BLEND);
00215     glEnable(GL_TEXTURE_2D);
00216     
00217     glDisable(GL_SCISSOR_TEST);
00218 }
00219 
00220 
00221 void GLPanosphereOverviewRenderer::Redraw()
00222 {
00223     glClearColor(0,0,0,0);
00224         glClear(GL_COLOR_BUFFER_BIT);
00225 
00226         glMatrixMode(GL_MODELVIEW);
00227 
00228         glLoadIdentity();
00229 
00230     double R = m_visualization_state->getR();
00231     double angx = m_visualization_state->getAngX();
00232     double angy = m_visualization_state->getAngY();
00233         
00234         gluLookAt(R * cos(angy) * cos(angx), R * sin(angy), R * cos(angy) * sin(angx), 0, 0, 0, 0, 1, 0);
00235     //for look from inside
00236 //      gluLookAt(0,0,0,R * cos(angy) * cos(angx), R * sin(angy), R * cos(angy) * sin(angx), 0, 1, 0);
00237 
00238     // draw things under the preview images
00239     // draw each active image.
00240     int imgs = m_pano->getNrOfImages();
00241     // offset by a half a pixel
00242     glPushMatrix();
00243 
00244     //draw the rectangle around the sphere
00245     glColor3f(0.5, 0.5, 0.5);
00246     
00247     double side = 150;
00248     glBegin(GL_LINE_LOOP);
00249 
00250         glVertex3f(-side,side,0);
00251         glVertex3f(side,side,0);
00252         glVertex3f(side,-side,0);
00253         glVertex3f(-side,-side,0);
00254 
00255     glEnd();
00256 
00257     //draw the axes, to give a sense of orientation
00258     double axis = 200;
00259     glBegin(GL_LINES);
00260 
00261         glColor3f(1,0,0);
00262         glVertex3f(-axis,0,0);
00263         glVertex3f(axis,0,0);
00264 
00265         glColor3f(0,1,0);
00266         glVertex3f(0,0,0);
00267         glVertex3f(0,axis,0);
00268 
00269         glColor3f(0,0,1);
00270         glVertex3f(0,0,0);
00271         glVertex3f(0,0,axis);
00272 
00273     glEnd();
00274 
00275 
00276     glEnable(GL_TEXTURE_2D);
00277 
00278     //To avoid z-order fight of the images if depth buffer is used, depth buffer is disabled and meshes are drawn twice,
00279     //first with back faces culled so that the inner face of the sphere is visible and below the outter face, 
00280     //and afterwards the meshes are drawn again with the front faces culled
00281     
00282     glEnable(GL_CULL_FACE);
00283     glCullFace(GL_BACK);
00284 
00285     //event called only before drawing of the images with front faces culled (the inner face of the panosphere)
00286     ((PanosphereOverviewToolHelper*)m_tool_helper)->BeforeDrawImagesBack();
00287     //generic draw before images are drawn (called twice with front and back faces culled)
00288     m_tool_helper->BeforeDrawImages();
00289 
00290     m_tex_man->Begin();
00291     // The old preview shows the lowest numbered image on top, so do the same:
00292     for (int img = imgs - 1; img != -1; img--)
00293     {
00294         // only draw active images
00295         if (m_pano->getImage(img).getActive())
00296         {
00297             // the tools can cancel drawing of images.
00298             if (m_tool_helper->BeforeDrawImageNumber(img))
00299             {
00300                 // the texture manager may need to call the display list
00301                 // multiple times with blending, so we pass it the display list
00302                 // rather than switching to the texture and then calling the
00303                 // list ourselves.
00304                 m_tex_man->DrawImage(img, m_mesh_man->GetDisplayList(img));
00305                 m_tool_helper->AfterDrawImageNumber(img);
00306             }
00307         }
00308     }
00309 
00310     m_tool_helper->AfterDrawImages();
00311     m_tex_man->DisableTexture();
00312     ((PanosphereOverviewToolHelper*)m_tool_helper)->AfterDrawImagesBack();
00313 
00314 //    #ifdef __WXGTK__
00333 //    #endif
00334 
00335     glMatrixMode(GL_MODELVIEW);
00336     glCullFace(GL_FRONT);
00337 
00338     ((PanosphereOverviewToolHelper*)m_tool_helper)->BeforeDrawImagesFront();
00339     m_tool_helper->BeforeDrawImages();
00340 
00341     // The old preview shows the lowest numbered image on top, so do the same:
00342     for (int img = imgs - 1; img != -1; img--)
00343     {
00344         // only draw active images
00345         if (m_pano->getImage(img).getActive())
00346         {
00347             // the tools can cancel drawing of images.
00348             if (m_tool_helper->BeforeDrawImageNumber(img))
00349             {
00350                 // the texture manager may need to call the display list
00351                 // multiple times with blending, so we pass it the display list
00352                 // rather than switching to the texture and then calling the
00353                 // list ourselves.
00354                 m_tex_man->DrawImage(img, m_mesh_man->GetDisplayList(img));
00355                 m_tool_helper->AfterDrawImageNumber(img);
00356             }
00357         }
00358     }
00359 
00360     m_tex_man->End();
00361     // drawn things after the active image.
00362     m_tool_helper->AfterDrawImages();
00363     m_tex_man->DisableTexture();
00364     ((PanosphereOverviewToolHelper*)m_tool_helper)->AfterDrawImagesFront();
00365     
00366     m_tex_man->DisableTexture();
00367 
00368     glDisable(GL_CULL_FACE);
00369 
00370     glPopMatrix();
00371 }
00372 
00373 vigra::Diff2D GLPanosphereOverviewRenderer::Resize(int w, int h)
00374 {
00375 
00376     width = w;
00377     height = h;
00378     glViewport(0, 0, width, height);
00379     // we use the view_state rather than the panorama to allow interactivity.
00380     HuginBase::PanoramaOptions *options = m_visualization_state->GetOptions();
00381     width_o = options->getWidth();
00382     height_o = options->getHeight();
00383 
00384     //since gluPerspective needs vertical field of view, depending on the aspect ratio we convert from vertical to horizontal FOV if needed
00385     double fov = m_visualization_state->getFOV();
00386     double fovy;
00387     if (h > w) {
00388         fovy = 2.0 * atan( tan(fov * M_PI / 360.0) * (float) h / (float) w) / M_PI * 180.0;
00389     } else {
00390         fovy = fov;
00391     }
00392 
00393         float ratio = 1.0* w / h;
00394 //      aspect = ratio;
00395         glMatrixMode(GL_PROJECTION);
00396         glLoadIdentity();
00397         glViewport(0, 0, w, h);
00398         gluPerspective(fovy,ratio,1,1000000);
00399 
00400     m_visualization_state->SetVisibleArea(vigra::Rect2D(0, 0, options->getWidth(),
00401                                              options->getHeight()));
00402 
00403     //calculate the scale depending on the section of the panosphere in the center of the screen
00404     double R = m_visualization_state->getR();
00405     double radius = m_visualization_state->getSphereRadius();
00406     //height of the screen in screen pixels over the length of the panosphere in panorama pixels when spread out
00407     double scrscale = (float) h  / (2 * tan(fovy / 360.0 * M_PI) * (R - radius) / (2 * radius * M_PI) * (options->getWidth()));
00408     m_visualization_state->SetScale(scrscale);
00409 //    DEBUG_DEBUG("renderer " << scrscale << " " << h << " " << R << " " << fovy);
00410 //    DEBUG_DEBUG("renderer scale " << scrscale);
00411 
00412 //    return vigra::Diff2D(w / 2, h / 2);
00413     return vigra::Diff2D(0,0);
00414 
00415 }
00416 
00417 void GLPlaneOverviewRenderer::Redraw()
00418 {
00419     // background color of mosaic plane
00420     glClearColor((float)m_background_color.Red()/255, (float)m_background_color.Green()/255, (float)m_background_color.Blue()/255,1.0);
00421 
00422         glClear(GL_COLOR_BUFFER_BIT);
00423 
00424         glMatrixMode(GL_MODELVIEW);
00425 
00426         glLoadIdentity();
00427 
00428     double R = m_visualization_state->getR();
00429 
00430         double X = m_visualization_state->getX();
00431         double Y = m_visualization_state->getY();
00432 
00433         gluLookAt(X,Y,R, X, Y, 0, 0, 1, 0);
00434 
00435     // draw things under the preview images
00436     m_tool_helper->BeforeDrawImages();
00437     int imgs = m_pano->getNrOfImages();
00438     glPushMatrix();
00439 
00440     glColor3f(0.5,0.5,0.5);
00441     double side = 150;
00442     glBegin(GL_LINE_LOOP);
00443 
00444         glVertex3f(-side,side,0);
00445         glVertex3f(side,side,0);
00446         glVertex3f(side,-side,0);
00447         glVertex3f(-side,-side,0);
00448 
00449     glEnd();
00450 
00451     double axis = 200;
00452     glBegin(GL_LINES);
00453 
00454         glColor3f(1,0,0);
00455         glVertex3f(-axis,0,0);
00456         glVertex3f(axis,0,0);
00457 
00458         glColor3f(0,1,0);
00459         glVertex3f(0,0,0);
00460         glVertex3f(0,axis,0);
00461 
00462         glColor3f(0,0,1);
00463         glVertex3f(0,0,0);
00464         glVertex3f(0,0,axis);
00465 
00466     glEnd();
00467 
00468 
00469     glEnable(GL_TEXTURE_2D);
00470 
00471     m_tex_man->Begin();
00472     // The old preview shows the lowest numbered image on top, so do the same:
00473     for (int img = imgs - 1; img != -1; img--)
00474     {
00475         // only draw active images
00476         if (m_pano->getImage(img).getActive())
00477         {
00478             // the tools can cancel drawing of images.
00479             if (m_tool_helper->BeforeDrawImageNumber(img))
00480             {
00481                 // the texture manager may need to call the display list
00482                 // multiple times with blending, so we pass it the display list
00483                 // rather than switching to the texture and then calling the
00484                 // list ourselves.
00485                 m_tex_man->DrawImage(img, m_mesh_man->GetDisplayList(img));
00486                 m_tool_helper->AfterDrawImageNumber(img);
00487             }
00488         }
00489     }
00490 
00491     m_tex_man->DisableTexture();
00492     m_tool_helper->AfterDrawImages();
00493 
00494     glMatrixMode(GL_MODELVIEW);
00495     
00496     m_tool_helper->BeforeDrawImages();
00497     // The old preview shows the lowest numbered image on top, so do the same:
00498     for (int img = imgs - 1; img != -1; img--)
00499     {
00500         // only draw active images
00501         if (m_pano->getImage(img).getActive())
00502         {
00503             // the tools can cancel drawing of images.
00504             if (m_tool_helper->BeforeDrawImageNumber(img))
00505             {
00506                 // the texture manager may need to call the display list
00507                 // multiple times with blending, so we pass it the display list
00508                 // rather than switching to the texture and then calling the
00509                 // list ourselves.
00510                 m_tex_man->DrawImage(img, m_mesh_man->GetDisplayList(img));
00511                 m_tool_helper->AfterDrawImageNumber(img);
00512             }
00513         }
00514     }
00515 
00516     m_tex_man->End();
00517     m_tex_man->DisableTexture();
00518     // drawn things after the active image.
00519     m_tool_helper->AfterDrawImages();
00520 
00521     glPopMatrix();
00522 }
00523 
00524 
00525 vigra::Diff2D GLPlaneOverviewRenderer::Resize(int w, int h)
00526 {
00527     width = w;
00528     height = h;
00529     glViewport(0, 0, width, height);
00530     // we use the view_state rather than the panorama to allow interactivity.
00531     HuginBase::PanoramaOptions *options = m_visualization_state->getViewState()->GetOptions();
00532     width_o = options->getWidth();
00533     height_o = options->getHeight();
00534 
00535     glMatrixMode(GL_PROJECTION);
00536     glLoadIdentity();  
00537 
00538     double fov = m_visualization_state->getFOV();
00539     double fovy;
00540     if (h > w) {
00541         fovy = 2.0 * atan( tan(fov * M_PI / 360.0) * (float) h / (float) w) / M_PI * 180.0;
00542     } else {
00543         fovy = fov;
00544     }
00545 
00546         float ratio = 1.0* w / h;
00547 //      aspect = ratio;
00548         glMatrixMode(GL_PROJECTION);
00549         glLoadIdentity();
00550         gluPerspective(fovy,ratio,1,1000000);
00551 
00552     m_visualization_state->SetVisibleArea(vigra::Rect2D(0, 0, options->getWidth(),
00553                                              options->getHeight()));
00554 
00555     double R = m_visualization_state->getR();
00556     double scrscale = (float) h / (2 * tan(fovy / 360.0 * M_PI) * R   * options->getWidth() / MeshManager::PlaneOverviewMeshInfo::scale);
00557     m_visualization_state->SetScale(scrscale);
00558 //    m_visualization_state->SetGLScale(gl_scale);
00559         
00560     return vigra::Diff2D(0,0);
00561 }
00562 

Generated on 23 Oct 2014 for Hugintrunk by  doxygen 1.4.7