diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp
index 59d62ffe3d834e19089faabac786a55c2bf6d74e..c6a0524b080d294537df86a59b4bf230c48b5686 100644
--- a/Common/VertexArray.cpp
+++ b/Common/VertexArray.cpp
@@ -31,11 +31,20 @@ void VertexArray::_addVertex(float x, float y, float z)
 
 void VertexArray::_addNormal(float nx, float ny, float nz)
 {
-  // storing the normals as bytes hurts rendering performance, but it
-  // significantly reduces the memory footprint
+#if defined(HAVE_VISUDEV)
   _normals.push_back(nx);
   _normals.push_back(ny);
   _normals.push_back(nz);
+#else
+  // storing the normals as bytes hurts rendering performance, but it
+  // significantly reduces the memory footprint
+  char cx = float2char(nx);
+  char cy = float2char(ny);
+  char cz = float2char(nz);
+  _normals.push_back(cx);
+  _normals.push_back(cy);
+  _normals.push_back(cz);
+#endif
 }
 
 void VertexArray::_addColor(unsigned char r, unsigned char g, unsigned char b,
@@ -128,9 +137,9 @@ void VertexArray::finalize()
 
 class AlphaElement {
  public:
-  AlphaElement(float *vp, float *np, unsigned char *cp) : v(vp), n(np), c(cp) {}
+  AlphaElement(float *vp, normal_type *np, unsigned char *cp) : v(vp), n(np), c(cp) {}
   float *v;
-  float *n;
+  normal_type *n;
   unsigned char *c;
 };
 
@@ -179,14 +188,14 @@ void VertexArray::sort(double x, double y, double z)
   elements.reserve(n);
   for(int i = 0; i < n; i++){
     float *vp = &_vertices[3 * npe * i];
-    float *np = _normals.empty() ? 0 : &_normals[3 * npe * i];
+    normal_type *np = _normals.empty() ? 0 : &_normals[3 * npe * i];
     unsigned char *cp = _colors.empty() ? 0 : &_colors[4 * npe * i];
     elements.push_back(AlphaElement(vp, np, cp));
   }
   std::sort(elements.begin(), elements.end(), AlphaElementLessThan());
 
   std::vector<float> sortedVertices;
-  std::vector<float> sortedNormals;
+  std::vector<normal_type> sortedNormals;
   std::vector<unsigned char> sortedColors;
   sortedVertices.reserve(_vertices.size());
   sortedNormals.reserve(_normals.size());
@@ -212,8 +221,9 @@ void VertexArray::sort(double x, double y, double z)
 
 double VertexArray::getMemoryInMb()
 {
-  int bytes = _vertices.size() * sizeof(float) + _normals.size() * sizeof(float) +
-    _colors.size() * sizeof(unsigned char);
+  int bytes = _vertices.size() * sizeof(float) +
+              _normals.size() * sizeof(normal_type) +
+              _colors.size() * sizeof(unsigned char);
   return (double)bytes / 1024. / 1024.;
 }
 
@@ -221,7 +231,9 @@ char *VertexArray::toChar(int num, std::string name, int type, double min, doubl
                           int numsteps, double time, SBoundingBox3d bbox, int &len)
 {
   int vn = _vertices.size(), nn = _normals.size(), cn = _colors.size();
-  int vs = vn * sizeof(float), ns = nn * sizeof(float), cs = cn * sizeof(unsigned char);
+  int vs = vn * sizeof(float),
+      ns = nn * sizeof(normal_type),
+      cs = cn * sizeof(unsigned char);
   int is = sizeof(int), ds = sizeof(double);
   int ss = name.size();
   double xmin = bbox.min().x(), ymin = bbox.min().y(), zmin = bbox.min().z();
@@ -311,7 +323,8 @@ void VertexArray::fromChar(int length, const char *bytes, int swap)
 
   int nn; memcpy(&nn, &bytes[index], is); index += is;
   if(nn){
-    _normals.resize(nn); int ns = nn * sizeof(float);
+    _normals.resize(nn);
+    int ns = nn * sizeof(normal_type);
     memcpy(&_normals[0], &bytes[index], ns); index += ns;
   }
 
diff --git a/Common/VertexArray.h b/Common/VertexArray.h
index 940e680339ccff7431fdbb0824e15b35f68101e9..73ebef79886ddede8375b68abad019e62d3e8c4a 100644
--- a/Common/VertexArray.h
+++ b/Common/VertexArray.h
@@ -11,6 +11,12 @@
 #include "SVector3.h"
 #include "SBoundingBox3d.h"
 
+#if defined(HAVE_VISUDEV)
+typedef float normal_type;
+#else
+typedef char normal_type;
+#endif
+
 class MElement;
 
 template<int N>
@@ -138,7 +144,7 @@ class VertexArray{
  private:
   int _numVerticesPerElement;
   std::vector<float> _vertices;
-  std::vector<float> _normals;
+  std::vector<normal_type> _normals;
   std::vector<unsigned char> _colors;
   std::vector<MElement*> _elements;
   std::set<ElementData<3>, ElementDataLessThan<3> > _data3;
@@ -168,9 +174,9 @@ class VertexArray{
   std::vector<float>::iterator lastVertex(){return _vertices.end();}
 
   // return a pointer to the raw normal array
-  float *getNormalArray(int i=0){ return &_normals[i]; }
-  std::vector<float>::iterator firstNormal(){return _normals.begin();}
-  std::vector<float>::iterator lastNormal(){return _normals.end();}
+  normal_type *getNormalArray(int i=0){ return &_normals[i]; }
+  std::vector<normal_type>::iterator firstNormal(){return _normals.begin();}
+  std::vector<normal_type>::iterator lastNormal(){return _normals.end();}
 
   // return a pointer to the raw color array
   unsigned char *getColorArray(int i=0){ return &_colors[i]; }
diff --git a/Fltk/contextWindow.cpp b/Fltk/contextWindow.cpp
index 5cce70f79df5cc359c11b7f8cb8263d20e6b4847..c583198b91b4e22b2078235b2daafad283ba992e 100644
--- a/Fltk/contextWindow.cpp
+++ b/Fltk/contextWindow.cpp
@@ -82,7 +82,7 @@ static void draw_stl(std::vector<SPoint3> &vertices, std::vector<SVector3> &norm
 
   glVertexPointer(3, GL_FLOAT, 0, va.getVertexArray());
   glEnableClientState(GL_VERTEX_ARRAY);
-  glNormalPointer(GL_FLOAT, 0, va.getNormalArray());
+  glNormalPointer(NORMAL_GLTYPE, 0, va.getNormalArray());
   glEnableClientState(GL_NORMAL_ARRAY);
   glDisableClientState(GL_COLOR_ARRAY);
   glDrawArrays(GL_TRIANGLES, 0, va.getNumVertices());
diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h
index 122caf2f61944b0103fd2f3f7e9fd31a05efb668..2e95d0ca541ac8b7a1ced69c210adbb36fe45161 100644
--- a/Graphics/drawContext.h
+++ b/Graphics/drawContext.h
@@ -27,6 +27,12 @@
 #include <GL/glu.h>
 #endif
 
+#if defined(HAVE_VISUDEV)
+#define NORMAL_GLTYPE GL_FLOAT
+#else
+#define NORMAL_GLTYPE GL_BYTE
+#endif
+
 class PView;
 class GModel;
 class GVertex;
diff --git a/Graphics/drawGeom.cpp b/Graphics/drawGeom.cpp
index 275c9305dc6004a8737682eef2ac6d0e205812e1..fa2d4b8eda754e12cf09bb0bafdecebed4cd2e6c 100644
--- a/Graphics/drawGeom.cpp
+++ b/Graphics/drawGeom.cpp
@@ -233,7 +233,7 @@ class drawGFace {
     glEnableClientState(GL_VERTEX_ARRAY);
     if(useNormalArray){
       glEnable(GL_LIGHTING);
-      glNormalPointer(GL_FLOAT, 0, va->getNormalArray());
+      glNormalPointer(NORMAL_GLTYPE, 0, va->getNormalArray());
       glEnableClientState(GL_NORMAL_ARRAY);
     }
     else{
diff --git a/Graphics/drawMesh.cpp b/Graphics/drawMesh.cpp
index 9c6a147c52f5b4d4b6e7760f886bd09a0156cf2f..8801d82a1bcb14f3b2ad86515dda36816d89fc78 100644
--- a/Graphics/drawMesh.cpp
+++ b/Graphics/drawMesh.cpp
@@ -367,7 +367,7 @@ static void drawArrays(drawContext *ctx, GEntity *e, VertexArray *va, GLint type
 
   if(useNormalArray){
     glEnable(GL_LIGHTING);
-    glNormalPointer(GL_FLOAT, 0, va->getNormalArray());
+    glNormalPointer(NORMAL_GLTYPE, 0, va->getNormalArray());
     glEnableClientState(GL_NORMAL_ARRAY);
   }
   else
diff --git a/Graphics/drawPost.cpp b/Graphics/drawPost.cpp
index 325439a9630772bdd8cc0381dace0ec1009b1f82..fa62dc231d3ddd9a5d5d54bc8e3052dc02e5059d 100644
--- a/Graphics/drawPost.cpp
+++ b/Graphics/drawPost.cpp
@@ -39,8 +39,12 @@ static void drawArrays(drawContext *ctx, PView *p, VertexArray *va, GLint type,
       glColor4ubv((GLubyte *)va->getColorArray(4 * i));
       double f = 1.;
       if(opt->pointType > 1){
-        float *n = va->getNormalArray(3 * i);
-        f = *n;
+#if defined(HAVE_VISUDEV)
+        f = *va->getNormalArray(3 * i);
+#else
+        char *n = va->getNormalArray(3 * i);
+        f = char2float(*n);
+#endif
       }
       if(opt->pointType == 2){
         int s = (int)(opt->pointSize * f);
@@ -62,25 +66,36 @@ static void drawArrays(drawContext *ctx, PView *p, VertexArray *va, GLint type,
       float *p1 = va->getVertexArray(3 * (i + 1));
       double x[2] = {p0[0], p1[0]}, y[2] = {p0[1], p1[1]}, z[2] = {p0[2], p1[2]};
       glColor4ubv((GLubyte *)va->getColorArray(4 * i));
-      if(opt->lineType == 2){
-        float *v0 = va->getNormalArray(3 * i);
-        float *v1 = va->getNormalArray(3 * (i + 1));
-        ctx->drawTaperedCylinder(opt->lineWidth, *v0, *v1, 0., 1., x, y, z, opt->light);
+      if (opt->lineType == 2){
+#if defined(HAVE_VISUDEV)
+        double v0 = *va->getNormalArray(3 * i);
+        double v1 = *va->getNormalArray(3 * (i + 1));
+#else
+        char *n0 = va->getNormalArray(3 * i);
+        char *n1 = va->getNormalArray(3 * (i + 1));
+        double v0 = char2float(*n0), v1 = char2float(*n1);
+#endif
+        ctx->drawTaperedCylinder(opt->lineWidth, v0, v1, 0., 1., x, y, z, opt->light);
       }
       else if (opt->lineType == 1)
         ctx->drawCylinder(opt->lineWidth, x, y, z, opt->light);
       else { // 2D (for now) MNT diagrams for frames
-	float l = sqrt ((p0[0] - p1[0]) * (p0[0] - p1[0]) +
+        float l = sqrt ((p0[0] - p1[0]) * (p0[0] - p1[0]) +
                         (p0[1] - p1[1]) * (p0[1] - p1[1]) +
                         (p0[2] - p1[2]) * (p0[2] - p1[2]) );
-        float *n0 = va->getNormalArray(3 * i);
-        float *n1 = va->getNormalArray(3 * (i + 1));
-        double v0 = *n0, v1 = *n1;
-	float dir [3] = {(p1[0] - p0[0]) / l , (p1[1] - p0[1]) / l , (p1[2] - p0[2]) / l};
-	printf("%g %g %g %g %g %g\n", v0, v1, p0[0], p0[1], p1[0], p1[1]);
-	ctx->drawVector(1, 0,
-			p0[0] - dir[1] * v0 , p0[1] + dir[0] * v0 , 0.0,
-			p1[0] - dir[1] * v1 , p1[1] + dir[0] * v1 , 0.0,opt->light);
+#if defined(HAVE_VISUDEV)
+        double v0 = *va->getNormalArray(3 * i);
+        double v1 = *va->getNormalArray(3 * (i + 1));
+#else
+        char *n0 = va->getNormalArray(3 * i);
+        char *n1 = va->getNormalArray(3 * (i + 1));
+        double v0 = char2float(*n0), v1 = char2float(*n1);
+#endif
+        float dir [3] = {(p1[0] - p0[0]) / l , (p1[1] - p0[1]) / l , (p1[2] - p0[2]) / l};
+        printf("%g %g %g %g %g %g\n", v0, v1, p0[0], p0[1], p1[0], p1[1]);
+        ctx->drawVector(1, 0,
+                        p0[0] - dir[1] * v0 , p0[1] + dir[0] * v0 , 0.0,
+                        p1[0] - dir[1] * v1 , p1[1] + dir[0] * v1 , 0.0,opt->light);
       }
     }
   }
@@ -89,7 +104,7 @@ static void drawArrays(drawContext *ctx, PView *p, VertexArray *va, GLint type,
     glEnableClientState(GL_VERTEX_ARRAY);
     if(useNormalArray){
       glEnable(GL_LIGHTING);
-      glNormalPointer(GL_FLOAT, 0, va->getNormalArray());
+      glNormalPointer(NORMAL_GLTYPE, 0, va->getNormalArray());
       glEnableClientState(GL_NORMAL_ARRAY);
     }
     else