OpenGLVisualizer.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  OpenGLVisualizer.cpp
00037 // Author:    Pedram Azad
00038 // Date:      2004
00039 // ****************************************************************************
00040 // Changes:   25.10.2010, Zhixing Xue
00041 //            * Added COpenGLVisualizer::GetDepthMatrix
00042 // ****************************************************************************
00043 
00044 
00045 // ****************************************************************************
00046 // Includes
00047 // ****************************************************************************
00048 
00049 #include "OpenGLVisualizer.h"
00050 #include "Calibration/Calibration.h"
00051 #include "Image/ByteImage.h"
00052 #include "Math/FloatMatrix.h"
00053 #include "Math/Math3d.h"
00054 #include "Math/Constants.h"
00055 
00056 #if defined __APPLE__
00057 #include <OpenGL/gl.h>
00058 #include <OpenGL/glu.h>
00059 #include <OpenGL/glext.h>
00060 #elif defined WIN32
00061 #include <windows.h>
00062 #include <GL/gl.h>
00063 #include <GL/glu.h>
00064 #include "glext.h"
00065 #else
00066 #include <GL/gl.h>
00067 #include <GL/glu.h>
00068 #include <GL/glx.h>
00069 #include <GL/glext.h>
00070 #endif
00071 
00072 #include <math.h>
00073 #include <stdio.h>
00074 
00075 
00076 // ****************************************************************************
00077 // Static variables
00078 // ****************************************************************************
00079 
00080 static GLuint bufferID;
00081 static bool bExtensionInitialized;
00082 
00083 #ifdef WIN32
00084 static PFNGLGENBUFFERSARBPROC glGenBuffers = 0;
00085 static PFNGLBINDBUFFERARBPROC glBindBuffer = 0;
00086 static PFNGLBUFFERDATAARBPROC glBufferData = 0;
00087 static PFNGLMAPBUFFERARBPROC glMapBuffer = 0;
00088 static PFNGLUNMAPBUFFERARBPROC glUnmapBuffer = 0;
00089 #endif
00090 
00091 const float COpenGLVisualizer::red[] = { 0.75f, 0, 0 };
00092 const float COpenGLVisualizer::green[] = { 0, 0.75f, 0 };
00093 const float COpenGLVisualizer::blue[] = { 0, 0, 0.75f };
00094 const float COpenGLVisualizer::yellow[] = { 0.65f, 0.5f, 0.49f };
00095 
00096 
00097 
00098 // ****************************************************************************
00099 // Constructor / Destructor
00100 // ****************************************************************************
00101 
00102 COpenGLVisualizer::COpenGLVisualizer()
00103 {
00104         bExtensionInitialized = false;
00105         m_pQuadric = 0;
00106         
00107         width = 0;
00108         height = 0;
00109         
00110         m_ViewMatrix.rotation = Math3d::unit_mat;
00111         m_ViewMatrix.translation = Math3d::zero_vec;
00112         m_bMatrixOnStack = false;
00113 }
00114 
00115 COpenGLVisualizer::~COpenGLVisualizer()
00116 {
00117         if (m_pQuadric)
00118                 gluDeleteQuadric(m_pQuadric);
00119 }
00120 
00121 
00122 // ****************************************************************************
00123 // Methods
00124 // ****************************************************************************
00125 
00126 void COpenGLVisualizer::SetProjectionMatrix(const CCalibration *pCalibration)
00127 {
00128         Mat3d K;
00129         
00130         if (pCalibration)
00131         {
00132                 width = pCalibration->GetCameraParameters().width;
00133                 height = pCalibration->GetCameraParameters().height;
00134                 pCalibration->GetCalibrationMatrix(K);
00135         }
00136         else
00137         {
00138                 // apply default values
00139                 width = 640;
00140                 height = 480;
00141                 Math3d::SetMat(K, 580, 0, 320, 0, 580, 240, 0, 0, 1);
00142         }
00143 
00144         // projection matrix
00145         glMatrixMode(GL_PROJECTION);
00146         glLoadIdentity();
00147         
00148         float m[16];
00149         CalculateOpenGLProjectionMatrix(K, width, height, 1, 4000, m);
00150         glMultMatrixf(m);
00151 
00152         // model view matrix
00153         glMatrixMode(GL_MODELVIEW);
00154         glLoadIdentity();
00155         glRotatef(180, 1, 0, 0);
00156 
00157         // account for extrinsic calibration
00158         if (pCalibration)
00159         {
00160                 float m[16];
00161                 Transformation3d transformation;
00162                 Math3d::SetMat(transformation.rotation, pCalibration->GetCameraParameters().rotation);
00163                 Math3d::SetVec(transformation.translation, pCalibration->GetCameraParameters().translation);
00164                 ConvertToOpenGLMatrix(transformation, m);
00165                 glMultMatrixf(m);
00166         }
00167 }
00168 
00169 void COpenGLVisualizer::SetProjectionMatrix(int nWidth, int nHeight)
00170 {
00171         Mat3d K;
00172         
00173         // apply default values for focal length and principal point
00174         width = nWidth;
00175         height = nHeight;
00176         const float w_factor = width / 640.0f;
00177         const float h_factor = height / 480.0f;
00178         Math3d::SetMat(K, 580 * w_factor, 0, 320 * w_factor, 0, 580 * h_factor, 240 * h_factor, 0, 0, 1);
00179 
00180         // projection matrix
00181         glMatrixMode(GL_PROJECTION);
00182         glLoadIdentity();
00183         
00184         float m[16];
00185         CalculateOpenGLProjectionMatrix(K, width, height, 1, 4000, m);
00186         glMultMatrixf(m);
00187 
00188         // model view matrix
00189         glMatrixMode(GL_MODELVIEW);
00190         glLoadIdentity();
00191         glRotatef(180, 1, 0, 0);
00192 }
00193 
00194 void COpenGLVisualizer::ActivateShading(bool bActivateShading)
00195 {
00196         if (bActivateShading)
00197         {
00198                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00199                 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00200                 glClearDepth(1.0f);
00201                 glDepthFunc(GL_LESS);
00202                 glEnable(GL_DEPTH_TEST);
00203                 glShadeModel(GL_SMOOTH);
00204                 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00205                 glEnable(GL_LIGHTING);
00206                 glEnable(GL_LIGHT0);
00207                 glEnable(GL_NORMALIZE);
00208                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00209                 //glEnable(GL_CULL_FACE);
00210         }
00211         else
00212         {
00213                 glDisable(GL_LIGHTING);
00214                 glDisable(GL_DEPTH_TEST);
00215                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00216         }
00217 }
00218 
00219 bool COpenGLVisualizer::Init(int nWidth, int nHeight, bool bActivateShading)
00220 {
00221         ActivateShading(bActivateShading);
00222 
00223         // set projection model
00224         SetProjectionMatrix(nWidth, nHeight);
00225         glViewport(0, 0, nWidth, nHeight);
00226         
00227         // create quadric object
00228         m_pQuadric = gluNewQuadric();
00229         
00230         // initialize extension for using pixel buffers for fast glReadPixels variant
00231         if (!InitExtension())
00232         {
00233                 //printf("info: pixel buffer extension is not available (slow method for glReadPixels will be used)\n");
00234                 return true;
00235         }
00236         
00237         #ifdef WIN32
00238         glGenBuffers(1, &bufferID);
00239         #endif
00240         
00241         return true;
00242 }
00243 
00244 bool COpenGLVisualizer::InitByCalibration(const CCalibration *pCalibration, bool bActivateShading)
00245 {
00246         ActivateShading(bActivateShading);
00247 
00248         // set projection model
00249         SetProjectionMatrix(pCalibration);
00250         glViewport(0, 0, width, height);
00251         
00252         // create quadric object
00253         m_pQuadric = gluNewQuadric();
00254         
00255         // initialize extension for using pixel buffers for fast glReadPixels variant
00256         if (!InitExtension())
00257         {
00258                 //printf("info: pixel buffer extension is not available (slow method for glReadPixels will be used)\n");
00259                 return true;
00260         }
00261         
00262         #ifdef WIN32
00263         glGenBuffers(1, &bufferID);
00264         #endif
00265         
00266         return true;
00267 }
00268 
00269 bool COpenGLVisualizer::GetImage(CByteImage *pDestinationImage)
00270 {
00271         if (pDestinationImage->width != width || pDestinationImage->height != height)
00272         {
00273                 printf("error: destination image does not match current mode\n");
00274                 return false;
00275         }
00276         
00277         if (bExtensionInitialized)
00278         {
00279                 #ifdef WIN32
00280                 // fast method
00281                 const int nBytes = width * height *pDestinationImage->bytesPerPixel;
00282                 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, bufferID);
00283                 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, nBytes, NULL, GL_STREAM_READ);
00284                 
00285                 if (pDestinationImage->type == CByteImage::eRGB24)
00286                         glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, 0);
00287                 else
00288                         glReadPixels(0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
00289                 
00290                 void *pData = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);   
00291                 memcpy(pDestinationImage->pixels, pData, nBytes);
00292                 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
00293                 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
00294                 #endif
00295         }
00296         else
00297         {
00298                 // slow method
00299                 if (pDestinationImage->type == CByteImage::eRGB24)
00300                         glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pDestinationImage->pixels);
00301                 else
00302                         glReadPixels(0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pDestinationImage->pixels);
00303         }
00304         
00305         return true;
00306 }
00307 
00308 bool COpenGLVisualizer::GetDepthMatrix(CFloatMatrix *pDestinationMatrix)
00309 {
00310         if (pDestinationMatrix->columns != width || pDestinationMatrix->rows != height)
00311         {
00312                 printf("error: destination matrix does not match current mode\n");
00313                 return false;
00314         }
00315         
00316         glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, pDestinationMatrix->data);
00317         
00318         return true;
00319 }
00320 
00321 void COpenGLVisualizer::Clear()
00322 {
00323         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00324         
00325         float m[16];
00326         ConvertToOpenGLMatrix(m_ViewMatrix, m);
00327         
00328         glMatrixMode(GL_MODELVIEW);
00329         
00330         if (m_bMatrixOnStack)
00331                 glPopMatrix();
00332                 
00333         glPushMatrix();
00334         glMultMatrixf(m);
00335         
00336         m_bMatrixOnStack = true;
00337 }
00338 
00339 void COpenGLVisualizer::DrawPoint(float x, float y, float z, const float *pColor)
00340 {
00341         if (pColor)
00342                 glColor3fv(pColor);
00343 
00344         glDisable(GL_LIGHTING);
00345 
00346         glBegin(GL_POINTS);
00347         glVertex3f(x, y, z);
00348         glEnd();
00349 
00350         glEnable(GL_LIGHTING);
00351 }
00352 
00353 void COpenGLVisualizer::DrawPoints(Vec3dList &points, const float *pColor)
00354 {
00355         if (pColor)
00356                 glColor3fv(pColor);
00357 
00358         glDisable(GL_LIGHTING);
00359 
00360         glBegin(GL_POINTS);
00361 
00362         const int c = (int) points.size();
00363         for (int i = 0; i < c; i++)
00364         {
00365                 const Vec3d &v = points.at(i);
00366                 glVertex3f(v.x, v.y, v.z);
00367 
00368                 if (c % 10000 == 0)
00369                 {
00370                         glEnd();
00371                         glBegin(GL_POINTS);
00372                 }
00373         }
00374 
00375         glEnd();
00376 
00377         glEnable(GL_LIGHTING);
00378 }
00379 
00380 void COpenGLVisualizer::DrawSphere(const Vec3d &point, float radius, const float *pColor)
00381 {
00382         glPushMatrix();
00383 
00384         glTranslated(point.x, point.y, point.z);
00385         if (pColor) glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pColor);
00386         gluSphere(m_pQuadric, radius, 50, 50);
00387         
00388         glPopMatrix();
00389 }
00390 
00391 void COpenGLVisualizer::DrawCylinder(const Vec3d &point1, const Vec3d &point2, float radius1, float radius2, const float color[3])
00392 {
00393         Vec3d u, _point1;
00394         Math3d::SubtractVecVec(point2, point1, u);
00395                 
00396         Math3d::SetVec(_point1, u);
00397         Math3d::MulVecScalar(_point1, 0.15f, _point1);
00398         Math3d::AddToVec(_point1, point1);
00399 
00400         const float length = Math3d::Length(u);
00401         Math3d::NormalizeVec(u);
00402         
00403         glPushMatrix();
00404 
00405         //glTranslated(_point1.x, _point1.y, _point1.z);
00406         glTranslated(point1.x, point1.y, point1.z);
00407         glRotatef(acosf(u.z) * 180.0f / FLOAT_PI, -u.y, u.x, 0.0f);
00408         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
00409         gluCylinder(m_pQuadric, radius1, radius2, length, 20, 20);
00410 
00411         glPopMatrix();
00412 }
00413 
00414 void COpenGLVisualizer::ConvertToOpenGLMatrix(const Transformation3d &transformation, float resultMatrix[16])
00415 {
00416         resultMatrix[0] = transformation.rotation.r1;
00417         resultMatrix[1] = transformation.rotation.r4;
00418         resultMatrix[2] = transformation.rotation.r7;
00419         resultMatrix[3] = 0;
00420         resultMatrix[4] = transformation.rotation.r2;
00421         resultMatrix[5] = transformation.rotation.r5;
00422         resultMatrix[6] = transformation.rotation.r8;
00423         resultMatrix[7] = 0;
00424         resultMatrix[8] = transformation.rotation.r3;
00425         resultMatrix[9] = transformation.rotation.r6;
00426         resultMatrix[10] = transformation.rotation.r9;
00427         resultMatrix[11] = 0;
00428         resultMatrix[12] = transformation.translation.x;
00429         resultMatrix[13] = transformation.translation.y;
00430         resultMatrix[14] = transformation.translation.z;
00431         resultMatrix[15] = 1;
00432 }
00433 
00434 void COpenGLVisualizer::DrawObject(const CFloatMatrix *pMatrix, const Transformation3d &transformation)
00435 {
00436         const int nTriangles = pMatrix->rows / 3;
00437         const float *data = pMatrix->data;
00438         float m[16];
00439 
00440         ConvertToOpenGLMatrix(transformation, m);
00441 
00442         glPushMatrix();
00443         glMultMatrixf(m);
00444 
00445         for (int i = 0, offset = 0; i < nTriangles; i++, offset += 18)
00446         {
00447                 glBegin(GL_TRIANGLES);
00448                 glNormal3f(data[offset], data[offset + 1], data[offset + 2]);
00449                 glVertex3f(data[offset + 3], data[offset + 4], data[offset + 5]);
00450                 glNormal3f(data[offset + 6], data[offset + 7], data[offset + 8]);
00451                 glVertex3f(data[offset + 9], data[offset + 10], data[offset + 11]);
00452                 glNormal3f(data[offset + 12], data[offset + 13], data[offset + 14]);
00453                 glVertex3f(data[offset + 15], data[offset + 16], data[offset + 17]);
00454                 glEnd();
00455         }
00456 
00457         glPopMatrix();
00458 }
00459 
00460 
00461 void COpenGLVisualizer::CalculateOpenGLProjectionMatrix(const Mat3d &K, int width, int height, float gnear, float gfar, float *m)
00462 {
00463         // note: for OpenGL, matrix must have column-major order!
00464         m[0] = (2.0f * K.r1 / width);
00465         m[1] = 0.0f;
00466         m[2] = 0.0f;
00467         m[3] = 0.0f;
00468         m[4] = (2.0f * K.r2 / width);
00469         m[5] = (2.0f * K.r5 / height);
00470         m[6] = 0.0f;
00471         m[7] = 0.0f;
00472         m[8] = -((2.0f * K.r3 / width) - 1.0f);
00473         m[9] = ((2.0f * K.r6 / height) - 1.0f);
00474         m[10] = -(gfar + gnear) / (gfar - gnear);
00475         m[11] = -1.0f;
00476         m[12] = 0.0f;
00477         m[13] = 0.0f;
00478         m[14] = -2.0f * gfar * gnear / (gfar - gnear);
00479         m[15] = 0.0f;
00480 }
00481 
00482 void COpenGLVisualizer::CalculateOpenGLProjectionMatrixDefaultPrincipalPoint(const Mat3d &K, int width, int height, float gnear, float gfar, float *m)
00483 {
00484         // note: for OpenGL, matrix must have column-major order!
00485         m[0] = (2.0f * K.r1 / width);
00486         m[1] = 0.0f;
00487         m[2] = 0.0f;
00488         m[3] = 0.0f;
00489         m[4] = (2.0f * K.r2 / width);
00490         m[5] = (2.0f * K.r5 / height);
00491         m[6] = 0.0f;
00492         m[7] = 0.0f;
00493         m[8] = 0.0f;
00494         m[9] = 0.0f;
00495         m[10] = -(gfar + gnear) / (gfar - gnear);
00496         m[11] = -1.0f;
00497         m[12] = 0.0f;
00498         m[13] = 0.0f;
00499         m[14] = -2.0f * gfar * gnear / (gfar - gnear);
00500         m[15] = 0.0f;
00501 }
00502 
00503 bool COpenGLVisualizer::InitExtension()
00504 {
00505         if (bExtensionInitialized)
00506                 return true;
00507         
00508         #ifdef WIN32
00509         glGenBuffers = (PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffersARB");
00510         glBindBuffer = (PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBufferARB");
00511         glBufferData = (PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferDataARB");
00512         glMapBuffer = (PFNGLMAPBUFFERARBPROC) wglGetProcAddress("glMapBufferARB");
00513         glUnmapBuffer = (PFNGLUNMAPBUFFERARBPROC) wglGetProcAddress("glUnmapBufferARB");
00514         bExtensionInitialized = glGenBuffers && glBindBuffer && glBufferData && glMapBuffer && glUnmapBuffer;
00515         #else
00516         /*glGenBuffers = (PFNGLGENBUFFERSARBPROC) glXGetProcAddress((const GLubyte *) "glGenBuffersARB");
00517         glBindBuffer = (PFNGLBINDBUFFERARBPROC) glXGetProcAddress((const GLubyte *) "glBindBufferARB");
00518         glBufferData = (PFNGLBUFFERDATAARBPROC) glXGetProcAddress((const GLubyte *) "glBufferDataARB");
00519         glMapBuffer = (PFNGLMAPBUFFERARBPROC) glXGetProcAddress((const GLubyte *) "glMapBufferARB");
00520         glUnmapBuffer = (PFNGLUNMAPBUFFERARBPROC) glXGetProcAddress((const GLubyte *) "glUnmapBufferARB");*/
00521         bExtensionInitialized = false;
00522         #endif
00523 
00524         return bExtensionInitialized;
00525 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:57