Esempio n. 1
0
void Set_Transparency()
{
   if (AntiAliasing == 0)
   {
      gl2psEnable(GL2PS_BLEND);
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   }
   glDepthMask(GL_FALSE);
}
Esempio n. 2
0
void draw_sph_flame(double radius, struct buffer_for_gl *gl_buf,
                    int iflag_write_ps){
	int i, j, k, nd, inum, ierr;
	double f_color[4];
	
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
	glVertexPointer(ITHREE, GL_FLOAT, IZERO, gl_buf->xyz);
	glColorPointer(IFOUR, GL_FLOAT, IZERO, gl_buf->rgba);
	
	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_LINE_STIPPLE);
	glLineStipple(1,0x3333);
    if (iflag_write_ps == ON) {ierr = gl2psEnable(GL2PS_LINE_STIPPLE);};
	
	set_black_color_c(f_color);
	
	inum = 0;
	for(j=0; j<NUM_P+1; j++){
		for(i=0; i<N_CURVE; i++){
			for (k=0; k<2; k++){
				gl_buf->xyz[ITWO*inum+k][0] = (GLfloat) (radius * sin(theta_p_grid[k+i]) * cos(phi_p_grid[j]));
				gl_buf->xyz[ITWO*inum+k][1] = (GLfloat) (radius * sin(theta_p_grid[k+i]) * sin(phi_p_grid[j]));
				gl_buf->xyz[ITWO*inum+k][2] = (GLfloat) (radius * cos(theta_p_grid[k+i]));
			};
			inum = inum + 1;
		}
	}
	
	for(j=0; j<NUM_T-1; j++){
		for(i=0; i<N_CURVE; i++){
			for (k=0; k<2; k++){
				gl_buf->xyz[ITWO*inum+k][0] = (GLfloat) (radius * sin(theta_t_grid[j]) * cos(phi_t_grid[i+k]));
				gl_buf->xyz[ITWO*inum+k][1] = (GLfloat) (radius * sin(theta_t_grid[j]) * sin(phi_t_grid[i+k]));
				gl_buf->xyz[ITWO*inum+k][2] = (GLfloat) (radius * cos(theta_t_grid[j]));
			};
			inum = inum + 1;
		}
	}
	
	for (j=0; j<ITWO*inum; j++) {
		for(nd=0;nd<4;nd++){gl_buf->rgba[j][nd] = f_color[nd];}
	}
	
	if(inum>0){glDrawArrays(GL_LINES, IZERO, (ITWO*inum));};
    
    if (iflag_write_ps == ON) {ierr = gl2psDisable(GL2PS_LINE_STIPPLE);};
	glDisable(GL_LINE_STIPPLE);
	
	
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);	
	return;
}
void draw_PSF_isoline(struct psf_data *psf_s, struct psf_menu_val *psf_m,
					  struct buffer_for_gl *gl_buf, int iflag_retina, int iflag_write_ps){
    int ierr;
	
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
	glVertexPointer(ITHREE, GL_FLOAT, IZERO, gl_buf->xyz);
	glColorPointer(IFOUR, GL_FLOAT, IZERO, gl_buf->rgba);
	
	glDisable(GL_CULL_FACE);
	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

	glLineWidth(HALF * ((float) iflag_retina+IONE));
    if (iflag_write_ps == ON) {
        ierr = gl2psLineWidth(ONE);
    };
	
	if(psf_m->draw_psf_grid  != 0){
        find_start_positive_lines(psf_m);
        if(psf_m->ist_positive_line > 1){
            glEnable(GL_LINE_STIPPLE);
            glLineStipple(1,0x3333);
            if (iflag_write_ps == ON) {ierr = gl2psEnable(GL2PS_LINE_STIPPLE);};

            draw_isolines_4_psf(IONE, psf_m->ist_positive_line,
                                psf_s, psf_m, gl_buf);
            
            if (iflag_write_ps == ON) {ierr = gl2psDisable(GL2PS_LINE_STIPPLE);};
            glDisable(GL_LINE_STIPPLE);
        };
        if(psf_m->ist_positive_line < psf_m->n_isoline){
            draw_isolines_4_psf(psf_m->ist_positive_line,
                                psf_m->n_isoline, psf_s, psf_m, gl_buf);
        };
    };
	if(psf_m->draw_psf_zero  != 0){
        glLineWidth( ((float) iflag_retina+IONE) );
        if (iflag_write_ps == ON) {ierr = gl2psLineWidth(TWO);};
        
        draw_zeroline_4_psf(psf_s, psf_m, gl_buf);
        
        glLineWidth(HALF * ((float) iflag_retina+IONE));
        if (iflag_write_ps == ON) {ierr = gl2psLineWidth(ONE);};
    };
	
	glEnable(GL_CULL_FACE);
	
	glDisableClientState(GL_COLOR_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY);
	return;
}
Esempio n. 4
0
static void drawVoronoiDual(std::vector<T*> &elements)
{
  glColor4ubv((GLubyte *) & CTX::instance()->color.fg);
  glEnable(GL_LINE_STIPPLE);
  glLineStipple(1, 0x0F0F);
  gl2psEnable(GL2PS_LINE_STIPPLE);
  glBegin(GL_LINES);
  for(unsigned int i = 0; i < elements.size(); i++){
    T *ele = elements[i];
    if(!isElementVisible(ele)) continue;
    SPoint3 pc = ele->circumcenter();
    if(ele->getDim() == 2){
      for(int j = 0; j < ele->getNumEdges(); j++){
        MEdge e = ele->getEdge(j);
        SVector3 p2p1(e.getVertex(1)->x() - e.getVertex(0)->x(),
                      e.getVertex(1)->y() - e.getVertex(0)->y(),
                      e.getVertex(1)->z() - e.getVertex(0)->z());
        SVector3 pcp1(pc.x() - e.getVertex(0)->x(),
                      pc.y() - e.getVertex(0)->y(),
                      pc.z() - e.getVertex(0)->z());
        double alpha = dot(pcp1,p2p1) / dot(p2p1,p2p1);
        SPoint3 p((1 - alpha)*e.getVertex(0)->x() + alpha * e.getVertex(1)->x(),
                  (1 - alpha)*e.getVertex(0)->y() + alpha * e.getVertex(1)->y(),
                  (1 - alpha)*e.getVertex(0)->z() + alpha * e.getVertex(1)->z());
        glVertex3d(pc.x(), pc.y(), pc.z());
        glVertex3d(p.x(), p.y(), p.z());
      }
    }
    else if(ele->getDim() == 3){
      for(int j = 0; j < ele->getNumFaces(); j++){
        MFace f = ele->getFace(j);
        SPoint3 p = f.barycenter();
        glVertex3d(pc.x(), pc.y(), pc.z());
        glVertex3d(p.x(), p.y(), p.z());
        for(int k = 0; k < f.getNumVertices(); k++){
          MEdge e(f.getVertex(k), (k == f.getNumVertices() - 1) ?
                  f.getVertex(0) : f.getVertex(k + 1));
          SPoint3 pe = e.barycenter();
          glVertex3d(p.x(), p.y(), p.z());
          glVertex3d(pe.x(), pe.y(), pe.z());
        }
      }
    }
  }
  glEnd();
  glDisable(GL_LINE_STIPPLE);
  gl2psDisable(GL2PS_LINE_STIPPLE);
}
Esempio n. 5
0
static void display(void)
{
  unsigned int i;
  unsigned int N = 50;
  const char *help = "Press 's' to save image or 'q' to quit";

  glClearColor(0.3, 0.5, 0.8, 0.);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  /* draw a smooth-shaded torus */
  glPushMatrix();
  glRotatef(-60., 2., 0., 1.);
  glEnable(GL_LIGHTING);
	/*  glutSolidTorus(0.3, 0.6, 30, 30);*/
	drawCube(0.5);
  glDisable(GL_LIGHTING);
  glPopMatrix();

  glColor3f(1.,1.,1.);

  /* draw a stippled line with many small segments (this tests the
     ability of gl2ps to render lines using as few strokes as
     possible) */
  glEnable(GL_LINE_STIPPLE);
  glLineStipple(1, 0x087F);
  gl2psEnable(GL2PS_LINE_STIPPLE);
  glBegin(GL_LINE_STRIP);
  for(i = 0; i < N; i++) glVertex3f(-0.75 + 1.5 * (double)i/(double)(N - 1), 0.75, -0.9);
  glEnd();
  glDisable(GL_LINE_STIPPLE);
  gl2psDisable(GL2PS_LINE_STIPPLE);

  /* draw a text string */
  glRasterPos2d(-0.9,-0.9);
  gl2psText(help, "Times-Roman", 24);
  for (i = 0; i < strlen(help); i++)
    glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, help[i]);

  glFlush();
}
Esempio n. 6
0
void Set_AntiAliasing()
{
   if (GetMultisample() > 0)
   {
      glEnable(GL_MULTISAMPLE);

#ifdef GL_MULTISAMPLE_FILTER_HINT_NV
      std::string s = (const char *)glGetString(GL_EXTENSIONS);
      if (s.find("GL_NV_multisample_filter_hint") != std::string::npos)
      {
         glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
      }
#endif
   }

   gl2psEnable(GL2PS_BLEND);
   glEnable(GL_BLEND);
   // glDisable(GL_DEPTH_TEST);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   // glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);

   glLineWidth(MS_LineWidth);

   // In order for polygon smoothing to work nicely, the polygons need to be
   // sorted by depth. Therefore we leave polygon smoothing to multisampling.
   if (0)
   {
      glEnable(GL_POLYGON_SMOOTH);
      glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
   }

   std::string vendor = (const char *)glGetString(GL_VENDOR);
   if (vendor.find("ATI") == std::string::npos || GetMultisample() <= 0)
   {
      // In order for line smoothing to blend nicely with polygons, we draw
      // the lines after the polygons.
      glEnable(GL_LINE_SMOOTH);
      glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
   }
   else
   {
#ifdef GLVIS_DEBUG
      std::cout <<
                "Found 'ATI' in the GL vendor string:"
                " using line smoothing via multisampling." << std::endl;
#endif
   }

   glEnable(GL_POINT_SMOOTH);
   glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);

   /* add fog
      glEnable(GL_AUTO_NORMAL);
      glEnable(GL_NORMALIZE);
      glEnable(GL_FOG);
      GLfloat fogColor[4] = {1.0, 1.0, 1.0, 1.0};
      GLint fogMode;
      fogMode = GL_EXP2;
      glFogi (GL_FOG_MODE, fogMode);
      glFogfv (GL_FOG_COLOR, fogColor);
      glFogf (GL_FOG_DENSITY, 2.0);
      glHint (GL_FOG_HINT, GL_NICEST);
   */

   AntiAliasing = 1;
}
Esempio n. 7
0
void draw_flame_4_map(struct buffer_for_gl *gl_buf, int iflag_write_ps){
	int i, j, nd, inum, ierr;
	double rtp_flame[6], d_map_flame[4], f_color[4];
	
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
	glVertexPointer(ITWO, GL_FLOAT, IZERO, gl_buf->xy);
	glColorPointer(IFOUR, GL_FLOAT, IZERO, gl_buf->rgba);
	
	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_LINE_STIPPLE);
	glLineStipple(1,0x3333);
    if (iflag_write_ps == ON) {ierr = gl2psEnable(GL2PS_LINE_STIPPLE);};
	
	set_black_color_c(f_color);
	
	inum = 0;
	rtp_flame[0] = ONE;
	rtp_flame[3] = ONE;
	for(j=0; j<NUM_P+1; j++){
		rtp_flame[2] = phi_p_grid[j];
		rtp_flame[5] = phi_p_grid[j];
		for(i=0; i<N_CURVE; i++){
			rtp_flame[1] = theta_p_grid[i];
			rtp_flame[4] = theta_p_grid[i+1];
			
			aitoff_c(ITWO, rtp_flame, d_map_flame);
			gl_buf->xy[ITWO*inum  ][0] = d_map_flame[0];
			gl_buf->xy[ITWO*inum  ][1] = d_map_flame[1];
			gl_buf->xy[ITWO*inum+1][0] = d_map_flame[2];
			gl_buf->xy[ITWO*inum+1][1] = d_map_flame[3];
			inum = inum + 1;
		}
	}
	
	for(j=0; j<NUM_T-1; j++){
		rtp_flame[1] = theta_t_grid[j] ;
		rtp_flame[4] = theta_t_grid[j];
		for(i=0; i<N_CURVE; i++){
			rtp_flame[2] = phi_t_grid[i];
			rtp_flame[5] = phi_t_grid[i+1];
			
			aitoff_c(ITWO, rtp_flame, d_map_flame);
			gl_buf->xy[ITWO*inum  ][0] = d_map_flame[0];
			gl_buf->xy[ITWO*inum  ][1] = d_map_flame[1];
			gl_buf->xy[ITWO*inum+1][0] = d_map_flame[2];
			gl_buf->xy[ITWO*inum+1][1] = d_map_flame[3];
			inum = inum + 1;
		}
	}
	for (j=0; j<ITWO*inum; j++) {
		for(nd=0;nd<4;nd++){gl_buf->rgba[j][nd] = f_color[nd];}
	}
	if(inum>0){glDrawArrays(GL_LINES, IZERO, (ITWO*inum));};
    
    if (iflag_write_ps == ON) {ierr = gl2psDisable(GL2PS_LINE_STIPPLE);};
	glDisable(GL_LINE_STIPPLE);
	
	
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);	
	return;
}
Esempio n. 8
0
void  display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    printOpenGLError();

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    
    gluLookAt(m_camera.position.x, m_camera.position.y, m_camera.position.z,
        m_camera.lookat.x, m_camera.lookat.y, m_camera.lookat.z,
        m_camera.up.x, m_camera.up.y, m_camera.up.z);
    printOglError(0,0);
    
    if(true)
    {
        gl2psEnable(GL2PS_LINE_STIPPLE);

        if(!noxyz) 
            UIHelper::drawXYZ();
        
        glPolygonMode(GL_FRONT_AND_BACK, polygon_mode);
        glColor3f(0.1, 0.8, 0);
        
        UIHelper::drawBoundingBox(boxobj2);

        
        {
            mat4 rotateMatrix = rotateDeg == 0 ? mat4::Identity : mat4::GetRotate(rotateDeg, rotateAxis);
            mat4 translateMatrix = mat4::GetTranslate(translatePos);
            mat4 transformMatrix = translateMatrix * rotateMatrix;
            {
                mat4 indentity = mat4::Identity;
             
                //double tx = 1.51, ty = 0, tz = 0;
                double tx = translatePos.x, ty = translatePos.y, tz = translatePos.z;
                double m [16] = {
                    1.0, 0, 0, 0,
                    0.0, 1.0, 0, 0,
                    0.0, 0, 1.0, 0,
                    tx, ty, tz, 1.0
                };
                {
                    dtSelectObject(&object1);
                    dtLoadMatrixd(m);
                    //dtLoadIdentity();
                    //dtTranslate(tx, ty, tz);
                    if(dtTestPair(&object1, &object2)) 
                    //if(dtTest() > 0)
                        glColor3f(1.0, 0, 0);
                    else
                        glColor3f(0.1, 0.8, 0);
                }
            }
        }
        
        if(rotateDeg != 0)
            glRotatef(rotateDeg, rotateAxis.x, rotateAxis.y, rotateAxis.z);
        glTranslatef(translatePos.x, translatePos.y, translatePos.z);
        UIHelper::drawBoundingBox(boxobj1);
        gl2psDisable(GL2PS_LINE_STIPPLE);
     
    }else
    {
        glColor3f(1, 0, 1);
        glPolygonMode(GL_FRONT_AND_BACK ,GL_LINE);
        glLineWidth(1.0); 
        GLUquadricObj *qobj = gluNewQuadric();
        gluSphere(qobj,3,16,16);
        glLineWidth(2.0);        
        UIHelper::drawNormals(normals, 3);
        glPointSize(5.0f);
        UIHelper::drawPoints(normals);
    }

    glPopMatrix();
    glFlush();

    if( finish_without_update )
        glFinish();
    else
        glutSwapBuffers();
}
/**
 * Renders the current scene to a file in the format given.
 *
 * @param filename The name of the target file. It must already contain the correct extension and must be encoded in UTF-8.
 * @param format The format of the file to render. Supported are PNG, PDF, PS (postscript) and EPS (encapsulated postscript).
 * @param title The titel for the document. Must be ANSI encoded for now.
 * @param software A string describing the producer of the document. Must be ANSI encoded for now.
 * @param content A set of flags indicating what additional info to render.
 * @param zoom The zoom at which render the file.
 * @param bounds Position and size of the area to store in the file (currently only for PNG).
 * @return True if successful otherwise false.
 */
bool CGenericCanvas::renderToFile(const char* filename, TGCFileFormat format, const char* title, const char* software,
                                  TGCRenderContent content, float zoom, TGCViewport& bounds)
{
  bool result = false;

  if (!updating())
  {
    beginUpdate();
    try
    {
      if ((FStates & GC_STATE_PENDING_ACTIVATION) != 0)
      {
        // A pending activation state always means there is a valid current view.
        FStates &= ~GC_STATE_PENDING_ACTIVATION;
        FCurrentView->activate();
      };

      switch (format)
      {
        case GC_FILE_FORMAT_PDF:
        case GC_FILE_FORMAT_PS:
        case GC_FILE_FORMAT_EPS:
          {
            if (FCurrentView != NULL)
            {
              const int fileTypeMapper[4] = {GL2PS_PDF, GL2PS_PS, GL2PS_EPS, GL2PS_TEX};

              FILE *file = openFile(filename, "wb");

              GLint bufferSize = 0;
              GLint state = GL2PS_OVERFLOW;
              
              char *oldlocale = setlocale(LC_NUMERIC, "C");
              while (state == GL2PS_OVERFLOW)
              {
                bufferSize += 1024 * 1024;
                gl2psBeginPage(title, software, NULL, fileTypeMapper[format], GL2PS_NO_SORT, GL2PS_DRAW_BACKGROUND | GL2PS_USE_CURRENT_VIEWPORT |
                  GL2PS_COMPRESS, GL_RGBA, 0, NULL, 0, 0, 0, bufferSize, file, filename);
                gl2psEnable(GL2PS_BLEND);
                gl2psBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

                clearBuffers();
                FCurrentView->render(content);

                state = gl2psEndPage();
              };
              setlocale(LC_NUMERIC, oldlocale);
              fclose(file);

              result = true;
            };
            break;
          };
        case GC_FILE_FORMAT_PNG:
          {
            if (FCurrentView != NULL)
            {
              TImage image;

              float workspaceWidth;
              float workspaceHeight;
              FCurrentView->getWorkspace(&workspaceWidth, &workspaceHeight);
              image.width = bounds.width;
              if (image.width < 0)
                image.width = (int) workspaceWidth;
              image.height = bounds.height;
              if (image.height < 0)
                image.height = (int) workspaceHeight;

              // If the frame buffer extension is not supported then there is no sense
              // to allocate a buffer larger than the current viewport,
              // because we cannot render more than this area in this case.
              if (!supportsExtension(GC_OE_FRAME_BUFFER_OBJECTS))
              {
                if (image.height > FCurrentView->viewportGet().height)
                  image.height = FCurrentView->viewportGet().height;
                if (image.width > FCurrentView->viewportGet().width)
                  image.width = FCurrentView->viewportGet().width;
              };

              image.colorType = COLOR_TYPE_RGB_ALPHA;
              image.data = (unsigned char*) malloc(image.width * image.height * 4);
              if (image.data != NULL)
              {
                FCurrentView->renderToMemory(GC_COLOR_FORMAT_RGBA, content, zoom, bounds, image.data);
                image.width = bounds.width;
                image.height = bounds.height;
                result = savePNG(utf8ToUtf16(filename), &image, true, title, software);
                free(image.data);
              };
            };
            break;
          };
      };
      endUpdate();
    }
    catch(...)
    {
      endUpdate();
      throw;
    };

    checkError();
  };

  return result;
}
Esempio n. 10
0
void extras()
{
  glColor3f(1., 0., 0.);

  glPointSize(1.);
  gl2psPointSize(1.);
  glBegin(GL_POINTS);
  glVertex3f(-1., 1.0, 0.);
  glEnd();

  glPointSize(3.);
  gl2psPointSize(3.);
  glBegin(GL_POINTS);
  glVertex3f(-0.8, 1.0, 0.);
  glEnd();

  glPointSize(5.);
  gl2psPointSize(5.);
  glBegin(GL_POINTS);
  glVertex3f(-0.6, 1.0, 0.);
  glEnd();

  glPointSize(7.);
  gl2psPointSize(7.);
  glBegin(GL_POINTS);
  glVertex3f(-0.4, 1.0, 0.);
  glEnd();

  glLineWidth(1.);
  gl2psLineWidth(1.);
  glBegin(GL_LINES);
  glVertex3f(-0.2, 1.05, 0.);
  glVertex3f(0.2, 1.05, 0.);
  glEnd();

  glEnable(GL_LINE_STIPPLE);
  glLineStipple(1, 0x087F);
  gl2psEnable(GL2PS_LINE_STIPPLE);
  glBegin(GL_LINES);
  glVertex3f(-0.2, 0.95, 0.);
  glVertex3f(0.2, 0.95, 0.);
  glEnd();
  glDisable(GL_LINE_STIPPLE);
  gl2psDisable(GL2PS_LINE_STIPPLE);

  glLineWidth(3.);
  gl2psLineWidth(3.);
  glBegin(GL_LINES);
  glVertex3f(0.4, 1.05, 0.);
  glVertex3f(0.8, 1.05, 0.);
  glEnd();

  glEnable(GL_LINE_STIPPLE);
  glLineStipple(2, 0x0F0F);
  /* glLineStipple(1, 0xAAAA); */
  gl2psEnable(GL2PS_LINE_STIPPLE);
  glBegin(GL_LINES);
  glVertex3f(0.4, 0.95, 0.);
  glVertex3f(0.8, 0.95, 0.);
  glEnd();
  glDisable(GL_LINE_STIPPLE);
  gl2psDisable(GL2PS_LINE_STIPPLE);

  glPointSize(1);
  gl2psPointSize(1);
  glLineWidth(1);
  gl2psLineWidth(1);
}
Esempio n. 11
0
static void display(void)
{
  unsigned int i;
  unsigned int N = 50;
  const char *help = "Press 's' to save image or 'q' to quit";

  glClearColor(0.3, 0.5, 0.8, 0.);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  /* draw a smooth-shaded torus */
  glPushMatrix();
  glRotatef(-60., 2., 0., 1.);
  glEnable(GL_LIGHTING);
  glutSolidTorus(0.3, 0.6, 30, 30);
  glDisable(GL_LIGHTING);
  glPopMatrix();


  /* draw three triangles on the same zplane and use polygon offset
     to order the layers: the grey triangle should be drawn on the
     middle layer */
  glEnable(GL_POLYGON_OFFSET_FILL);
  glPolygonOffset(1.0, 1.0);
  gl2psEnable(GL2PS_POLYGON_OFFSET_FILL);
  glColor3f(0.,0.,0.);
  glBegin(GL_TRIANGLES);
  glVertex3f(0.6, 0.8, 0);
  glVertex3f(0.8, 0.8, 0);
  glVertex3f(0.7, 0.92, 0);
  glEnd();

  glPolygonOffset(2.0, 2.0);
  gl2psEnable(GL2PS_POLYGON_OFFSET_FILL);
  glColor3f(1.,1.,1.);
  glBegin(GL_TRIANGLES);
  glVertex3f(0.7, 0.8, 0);
  glVertex3f(0.9, 0.8, 0);
  glVertex3f(0.8, 0.92, 0);
  glEnd();

  glPolygonOffset(1.5, 1.5);
  gl2psEnable(GL2PS_POLYGON_OFFSET_FILL);
  glColor3f(0.5,0.5,0.5);
  glBegin(GL_TRIANGLES);
  glVertex3f(0.65, 0.86, 0);
  glVertex3f(0.85, 0.86, 0);
  glVertex3f(0.75, 0.98, 0);
  glEnd();

  glDisable(GL_POLYGON_OFFSET_FILL);
  gl2psDisable(GL2PS_POLYGON_OFFSET_FILL);

  glColor3f(0.1,0.1,0.1);

  /* draw a stippled line with many small segments (this tests the
     ability of gl2ps to render lines using as few strokes as
     possible) */
  glEnable(GL_LINE_STIPPLE);
  glLineStipple(1, 0x087F);
  gl2psEnable(GL2PS_LINE_STIPPLE);
  glBegin(GL_LINE_STRIP);
  for(i = 0; i < N; i++)
    glVertex3f(-0.75 + 1.5 * (double)i/(double)(N - 1), 0.75, -0.9);
  glEnd();
  glDisable(GL_LINE_STIPPLE);
  gl2psDisable(GL2PS_LINE_STIPPLE);

  /* draw a text string */
  glRasterPos2d(-0.9,-0.9);
  gl2psText(help, "Times-Roman", 24);
  for (i = 0; i < strlen(help); i++)
    glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, help[i]);

  glFlush();
}