From a562944023fd0de61a9751affa4ad51d7d718621 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 16 Dec 2005 19:17:34 +0000
Subject: [PATCH] cleanup+add comments so that students can understand what's
 going on with the projection stuff.

(still need to cleanup the zooming in handle() to use gluUnproject() instead
of the ad-hock stuff that only works for an orthographic proj)
---
 Fltk/Opengl_Window.cpp  |  3 +-
 Graphics/CreateFile.cpp |  3 +-
 Graphics/Draw.cpp       | 84 ++++++++++++++++++-----------------------
 Graphics/Draw.h         | 10 ++---
 Graphics/Mesh.cpp       | 12 +++---
 5 files changed, 48 insertions(+), 64 deletions(-)

diff --git a/Fltk/Opengl_Window.cpp b/Fltk/Opengl_Window.cpp
index 7287e55275..42f472117a 100644
--- a/Fltk/Opengl_Window.cpp
+++ b/Fltk/Opengl_Window.cpp
@@ -1,4 +1,4 @@
-// $Id: Opengl_Window.cpp,v 1.51 2005-12-16 17:35:33 geuzaine Exp $
+// $Id: Opengl_Window.cpp,v 1.52 2005-12-16 19:17:33 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -64,7 +64,6 @@ void Opengl_Window::draw()
 
   if(!ZoomMode) {
     ClearOpengl();
-    Orthogonalize(0, 0);
     Draw3d();
     Draw2d();
   }
diff --git a/Graphics/CreateFile.cpp b/Graphics/CreateFile.cpp
index e5f9fca99b..d0d28fa240 100644
--- a/Graphics/CreateFile.cpp
+++ b/Graphics/CreateFile.cpp
@@ -1,4 +1,4 @@
-// $Id: CreateFile.cpp,v 1.70 2005-12-16 17:35:33 geuzaine Exp $
+// $Id: CreateFile.cpp,v 1.71 2005-12-16 19:17:33 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -41,7 +41,6 @@ void FillBuffer(void)
 {
   SetOpenglContext();
   ClearOpengl();
-  Orthogonalize(0, 0);
   Draw3d();
   Draw2d();
 }
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index 59c7d58472..da79246cfa 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.81 2005-12-16 17:35:33 geuzaine Exp $
+// $Id: Draw.cpp,v 1.82 2005-12-16 19:17:34 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -75,6 +75,8 @@ void Draw3d(void)
   glDepthFunc(GL_LESS);
   glEnable(GL_DEPTH_TEST);
 
+  InitProjection(0, 0);
+  InitPosition();
   InitRenderModel();
 
   Draw_Mesh(&M);
@@ -129,38 +131,25 @@ void ClearOpengl(void)
   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 }
 
-// Ortho
+// Init
 
-void Orthogonalize(int x, int y)
+void InitProjection(int x, int y)
 {
-  double Va, Wa;
-
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-
-  if(CTX.render_mode == GMSH_SELECT)
-    gluPickMatrix((GLdouble) x,
-                  (GLdouble) (CTX.viewport[3] - y),
-                  5.0, 5.0, (GLint *) CTX.viewport);
-
-  Va = (GLdouble) (CTX.viewport[3] - CTX.viewport[1]) /
+  double Va = 
+    (GLdouble) (CTX.viewport[3] - CTX.viewport[1]) /
     (GLdouble) (CTX.viewport[2] - CTX.viewport[0]);
+  double Wa = (CTX.max[1] - CTX.min[1]) / (CTX.max[0] - CTX.min[0]);
 
-  Wa = (CTX.max[1] - CTX.min[1]) / (CTX.max[0] - CTX.min[0]);
-
+  // compute the viewport in World coordinates (with margins)
   if(Va > Wa) {
     CTX.vxmin = CTX.min[0];
     CTX.vxmax = CTX.max[0];
-    CTX.vymin =
-      0.5 * (CTX.min[1] + CTX.max[1] - Va * (CTX.max[0] - CTX.min[0]));
-    CTX.vymax =
-      0.5 * (CTX.min[1] + CTX.max[1] + Va * (CTX.max[0] - CTX.min[0]));
+    CTX.vymin = 0.5 * (CTX.min[1] + CTX.max[1] - Va * (CTX.max[0] - CTX.min[0]));
+    CTX.vymax = 0.5 * (CTX.min[1] + CTX.max[1] + Va * (CTX.max[0] - CTX.min[0]));
   }
   else {
-    CTX.vxmin =
-      0.5 * (CTX.min[0] + CTX.max[0] - (CTX.max[1] - CTX.min[1]) / Va);
-    CTX.vxmax =
-      0.5 * (CTX.min[0] + CTX.max[0] + (CTX.max[1] - CTX.min[1]) / Va);
+    CTX.vxmin = 0.5 * (CTX.min[0] + CTX.max[0] - (CTX.max[1] - CTX.min[1]) / Va);
+    CTX.vxmax = 0.5 * (CTX.min[0] + CTX.max[0] + (CTX.max[1] - CTX.min[1]) / Va);
     CTX.vymin = CTX.min[1];
     CTX.vymax = CTX.max[1];
   }
@@ -169,21 +158,24 @@ void Orthogonalize(int x, int y)
   CTX.vymin -= (CTX.vymax - CTX.vymin) / 3.;
   CTX.vymax += 0.25 * (CTX.vymax - CTX.vymin);
 
-  CTX.pixel_equiv_x =
-    (CTX.vxmax - CTX.vxmin) / (CTX.viewport[2] - CTX.viewport[0]);
-  CTX.pixel_equiv_y =
-    (CTX.vymax - CTX.vymin) / (CTX.viewport[3] - CTX.viewport[1]);
+  // store what one pixel represents in world coordinates
+  CTX.pixel_equiv_x = (CTX.vxmax - CTX.vxmin) / (CTX.viewport[2] - CTX.viewport[0]);
+  CTX.pixel_equiv_y = (CTX.vymax - CTX.vymin) / (CTX.viewport[3] - CTX.viewport[1]);
 
-  // We should have a look at how the scaling is done in "real" opengl
-  // applications (I guess they normalize the scene to fit in a 1x1x1
-  // box or something...). Here, we set up a large box around the
-  // object, so that if we zoom a lot the resolution of the depth
-  // buffer might become insufficient (at least with the "software"
-  // Mesa on Linux; with hardware acceleration or on Windows
-  // everyhting seems to be fine).
+  // setup ortho or perspective projection matrix
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+
+  if(CTX.render_mode == GMSH_SELECT)
+    gluPickMatrix((GLdouble) x, (GLdouble) (CTX.viewport[3] - y),
+                  5.0, 5.0, (GLint *) CTX.viewport);
 
   double gradient_zdist, gradient_xyfact;
   if(CTX.ortho) {
+    // setting up the near and far clipping planes so that the box is
+    // large enough to manipulate the model and zoom, but not too big
+    // (the z-buffer resolution, e.g., on software Mesa can become
+    // insufficient)
     double maxz = MAX(fabs(CTX.min[2]), fabs(CTX.max[2]));
     if(maxz < CTX.lc) maxz = CTX.lc;
     double clip = maxz * CTX.s[2] * CTX.clip_factor;
@@ -196,18 +188,15 @@ void Orthogonalize(int x, int y)
   else {
     double near = 0.75 * CTX.clip_factor * CTX.lc;
     double far = 75. * CTX.clip_factor * CTX.lc;
-
     // recenter the model such that the perspective is always at the
     // center of the screen. FIXME: this screws up the zoom, so let's
     // leave it out for now
-    /*
-    double w = (CTX.max[0] - CTX.min[0]) / 2.;
-    double h = (CTX.max[1] - CTX.min[1]) / 2.;
-    CTX.vxmin -= w;
-    CTX.vxmax -= w;
-    CTX.vymin -= h;
-    CTX.vymax -= h;
-    */
+    //double w = (CTX.max[0] - CTX.min[0]) / 2.;
+    //double h = (CTX.max[1] - CTX.min[1]) / 2.;
+    //CTX.vxmin -= w;
+    //CTX.vxmax -= w;
+    //CTX.vymin -= h;
+    //CTX.vymax -= h;
     double w = 0.;
     double h = 0.;
     glFrustum(CTX.vxmin, CTX.vxmax, CTX.vymin, CTX.vymax, near, far);
@@ -220,7 +209,7 @@ void Orthogonalize(int x, int y)
   }
 
   // draw background gradient
-  if(CTX.bg_gradient){
+  if(CTX.render_mode != GMSH_SELECT && CTX.bg_gradient){
     glPushMatrix();
     glLoadIdentity();
     glTranslated(0., 0., -gradient_zdist);
@@ -247,8 +236,6 @@ void Orthogonalize(int x, int y)
   }
 }
 
-// Init
-
 void InitRenderModel(void)
 {
   GLfloat r, g, b;
@@ -355,7 +342,8 @@ void Process_SelectionBuffer(int x, int y, int *n, hit *hits)
 		 // an entity is drawn
 
   glPushMatrix();
-  Orthogonalize(x, y);
+  InitProjection(x, y);
+  InitPosition();
   Draw_Mesh(&M);
   glPopMatrix();
 
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 0c8804e5e1..66f9052a25 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -30,12 +30,12 @@
 
 #define SELECTION_BUFFER_SIZE  1024
 
-void InitRenderModel(void);
-void InitPosition(void);
-
-void Orthogonalize(int x, int y);
-void ClearOpengl(void);
 void SetOpenglContext(void);
+void ClearOpengl(void);
+
+void InitProjection(int x, int y);
+void InitPosition(void);
+void InitRenderModel(void);
 
 typedef struct{
   unsigned int type, ient, depth;
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 7359b5f97a..77e8e2400a 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.144 2005-12-16 17:35:33 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.145 2005-12-16 19:17:34 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -56,18 +56,18 @@ static int stepLabelsDisplayed = 1;
 void draw_polygon_2d(double r, double g, double b, int n,
                      double *x, double *y, double *z)
 {
-  int i;
-
+  // this routine is only used to display the interactive construction
+  // of the 2D aniso mesh
   CalculateMinMax(THEM->Points, NULL);
   SetOpenglContext();
-  Orthogonalize(0, 0);
+  InitProjection(0, 0);
   InitPosition();
 
   glDisable(GL_DEPTH_TEST);
   glDrawBuffer(GL_FRONT);
   glColor3f(r, g, b);
   glBegin(GL_LINE_STRIP);
-  for(i = 0; i < n; i++)
+  for(int i = 0; i < n; i++)
     if(z)
       glVertex3d(x[i], y[i], z[i]);
     else
@@ -141,8 +141,6 @@ int getPartition(int index)
 
 void Draw_Mesh(Mesh * M)
 {
-  InitPosition();
-
   for(int i = 0; i < 6; i++)
     glClipPlane((GLenum)(GL_CLIP_PLANE0 + i), CTX.clip_plane[i]);
 
-- 
GitLab