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

Generated on 2 Dec 2016 for Hugintrunk by  doxygen 1.4.7