Projector.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:3k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. // Projector.cc      Classes for easily simulating OpenGL
  2. //                   projection/unprojection
  3. // created 5/5/99    magi@cs.stanford.edu
  4. #include "Projector.h"
  5. #include "Trackball.h"
  6. #include "TbObj.h"
  7. #include "plvGlobals.h"
  8. // these variables are declared and initialized in plvAnalyze.cc
  9. extern unsigned int g_zbufferMaxUI;
  10. extern float g_zbufferMaxF;
  11. Projector::Projector (Trackball* tb, TbObj* tbobj)
  12. {
  13.   // Some naughty clients of this code try to initialize a Projector
  14.   // before there's an OpenGL context (e.g. during static variable
  15.   // initialization).  Some OpenGL implementations don't appreciate
  16.   // our trying to run OpenGL commands at this time, so try to prevent this...
  17.   if (!g_glVersion)
  18.    return;
  19.   GLdouble model[16], proj[16];
  20.   glGetDoublev(GL_PROJECTION_MATRIX, proj);    // current GL state
  21.   int vp[4];
  22.   glGetIntegerv(GL_VIEWPORT, vp);
  23.   width = vp[2]; height = vp[3];
  24.   int matrixMode;
  25.   glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
  26.   glMatrixMode (GL_MODELVIEW);
  27.   glPushMatrix();
  28.   if (tb || tbobj) { // if both NULL, use current state
  29.     // things that want true identity modelview have to set it that way
  30.     // themselves, then call with both tb and tbobj NULL
  31.     glLoadIdentity ();
  32.     if (tb)
  33.       tb->applyXform();
  34.     if (tbobj)
  35.       tbobj->gl_xform();
  36.   }
  37.   glGetDoublev(GL_MODELVIEW_MATRIX, model);    // applied from trackball
  38.   glPopMatrix();
  39.   glMatrixMode ((GLenum) matrixMode);
  40.   xfForward = Xform<float>(proj) * Xform<float>(model);
  41. }
  42. Pnt3
  43. Projector::operator() (const Pnt3& world) const
  44. {
  45.   Pnt3 screen = world;
  46.   xfForward (screen);
  47.   float winX = width * (screen[0] + 1) / 2;
  48.   float winY = height * (screen[1] + 1) / 2;
  49.   float winZ = (screen[2] + 1) / 2;
  50.   return Pnt3 (winX, winY, winZ);
  51. }
  52. void
  53. Projector::xformBy (const Xform<float>& xfRel)
  54. {
  55.   // BUGBUG suspect code!  needs testing.
  56.   xfForward = xfForward * xfRel;
  57. }
  58. //////////////////////////////////////////////////////////////////////
  59. //
  60. // Unprojector
  61. //
  62. //////////////////////////////////////////////////////////////////////
  63. Unprojector::Unprojector (Trackball* tb, TbObj* tbobj)
  64.   : Projector (tb, tbobj)
  65. {
  66.   xfBack = xfForward;
  67.   xfBack.invert();
  68. }
  69. Pnt3
  70. Unprojector::operator() (int x, int y, unsigned int z) const
  71. {
  72.   float tx = (2. * x / width) - 1;
  73.   float ty = (2. * y / height) - 1;
  74.   // The line below used to just say (2. * z / (float) g_zbufferMaxUI),
  75.   // but MSVC++ v.6 does the wrong thing without the extra parens! -- DRK
  76.   float tz = (2. * z / ((float)g_zbufferMaxUI)) - 1;
  77.   return xfBack.unproject (tx, ty, tz);
  78. }
  79. Pnt3
  80. Unprojector::operator() (int x, int y, float z) const
  81. {
  82.   float tx = (2. * x / width) - 1;
  83.   float ty = (2. * y / height) - 1;
  84.   float tz = (2. * z / g_zbufferMaxF) - 1;
  85.   return xfBack.unproject (tx, ty, tz);
  86. }
  87. Pnt3
  88. Unprojector::forward (const Pnt3& world) const
  89. {
  90.   return Projector::operator() (world);
  91. }
  92. void
  93. Unprojector::xformBy (const Xform<float>& xfRel)
  94. {
  95.   Projector::xformBy (xfRel);
  96.   // BUGBUG suspect code!  needs testing.
  97.   Xform<float> xfRelInv = xfRel; xfRelInv.invert();
  98.   xfBack = xfRelInv * xfBack;
  99. }