Click here to Skip to main content
Click here to Skip to main content
Articles » Multimedia » OpenGL » General » Downloads
 
Add your own
alternative version
Go to top

Achieving PostScript and Wmf outputs for OpenGL

, 9 Jun 2003
This article explains how to generate resolution independent versions of 3D meshes rendered by OpenGL/MFC programs, i.e. how to export the rendering results to vectorial formats such as encapsulated postscript (EPS) and Windows enhanced metafile (EMF) formats. The main goal consists of being able to
gl_export.zip
Src
Mesh.dsp
Mesh.dsw
Mesh.plg
Mesh.aps
Mesh.clw
Lib3D
res
Mesh.ico
MeshDoc.ico
Toolbar.bmp
Mesh.ncb
Mesh.opt
Bin
knot2.wrl
mnt.wrl
mannequin.wrl
venus.wrl
knot1.wrl
nefertiti.wrl
geosphere.wrl
metafile.emf
Mesh.exe
samples_eps.zip
nefertiti_flat.eps
nefertiti_line_light.eps
nefertiti_line.eps
nefertiti_line_color.eps
nefertiti_smooth_light.eps
nefertiti_line_smooth_light.eps
nefertiti_vertex_color.eps
sample_ppt.zip
sample.ppt
//********************************************
// PsRender.h
// class CPsRenderer
//********************************************
// alliez@usc.edu
// Adapted from :
//   Frederic Delhoume
//   Mark Kilgards 
// http://reality.sgi.com/opengl/tips/Feedback.html
// Created : 18/11/99
// Modified : 20/10/00
//********************************************

// Code below is nothing more than Mark J. Kilgard's code
// adapted for C++/MFC

/* Copyright (c) Mark J. Kilgard, 1997. */

/* This program is freely distributable without licensing fees 
   and is provided without guarantee or warrantee expressed or 
   implied. This program is -not- in the public domain. */

/* Example showing how to use OpenGL's feedback mode to capture
   transformed vertices and output them as Encapsulated PostScript.
   Handles limited hidden surface removal by sorting and does
   smooth shading (albeit limited due to PostScript). */


#ifndef _PS_RENDERER_
#define _PS_RENDERER_

#define EPS_SMOOTH_LINE_FACTOR 0.06
#define EPS_GOURAUD_THRESHOLD  0.05
#define EPS_LINE_WIDTH         0.1

#ifndef __GL_H__
	#include <gl/gl.h>
	#include <gl/glu.h>
#endif // __GL_H__

class CPsRenderer
{
	GLfloat m_PointSize;

public:
	CPsRenderer() {}
	~CPsRenderer() {}

public:
	void Run(char *pFilename,GLfloat *pFeedbackBuffer,int NbValues,BOOL sort);

private:
	static int compare(const void *a, const void *b);
	GLfloat *spewPrimitiveEPS(FILE * file, GLfloat * loc);
	void spewWireFrameEPS(FILE * file, BOOL  doSort,GLint size, GLfloat * buffer);
	void spewUnsortedFeedback(FILE * file, GLint size, GLfloat * buffer);
	void spewSortedFeedback(FILE * file, GLint size, GLfloat * buffer);
};

typedef struct _DepthIndex {
  GLfloat *ptr;
  GLfloat depth;
} DepthIndex;

/* OpenGL's GL_3D_COLOR feedback vertex format. */
typedef struct _Feedback3Dcolor {
  GLfloat x;
  GLfloat y;
  GLfloat z;
  GLfloat red;
  GLfloat green;
  GLfloat blue;
  GLfloat alpha;
} Feedback3Dcolor;


static char *NicegouraudtriangleEPS[] =
{
  "\n% Smooth-shaded triangle - x3 y3 r3 g3 b3 x2 y2 r2 g2 b2 x1 y1 r1 g1 b1 ST",
  "/ST {",
  "	/b1 exch def",
  "	/g1 exch def",
  "	/r1 exch def",
  "	/y1 exch def",
  "	/x1 exch def",
  "	/b2 exch def",
  "	/g2 exch def",
  "	/r2 exch def",
  "	/y2 exch def",
  "	/x2 exch def",
  "	/b3 exch def",
  "	/g3 exch def",
  "	/r3 exch def",
  "	/y3 exch def",
  "	/x3 exch def",
  "	b2 b1 sub abs 0.05 gt",
  "	g2 g1 sub abs 0.017 gt",
  "	r2 r1 sub abs 0.032 gt",
  "	b3 b1 sub abs 0.05 gt",
  "	g3 g1 sub abs 0.017 gt",
  "	r3 r1 sub abs 0.032 gt",
  "	b2 b3 sub abs 0.05 gt",
  "	g2 g3 sub abs 0.017 gt",
  "	r2 r3 sub abs 0.032 gt",
  "	or or or or or or or or {",
  "		/b12 b1 b2 add 0.5 mul def",
  "		/g12 g1 g2 add 0.5 mul def",
  "		/r12 r1 r2 add 0.5 mul def",
  "		/y12 y1 y2 add 0.5 mul def",
  "		/x12 x1 x2 add 0.5 mul def",
  "		/b13 b1 b3 add 0.5 mul def",
  "		/g13 g1 g3 add 0.5 mul def",
  "		/r13 r1 r3 add 0.5 mul def",
  "		/y13 y1 y3 add 0.5 mul def",
  "		/x13 x1 x3 add 0.5 mul def",
  "		/b32 b3 b2 add 0.5 mul def",
  "		/g32 g3 g2 add 0.5 mul def",
  "		/r32 r3 r2 add 0.5 mul def",
  "		/y32 y3 y2 add 0.5 mul def",
  "		/x32 x3 x2 add 0.5 mul def",
  "		x1 y1 r1 g1 b1 x12 y12 r12 g12 b12 x13 y13 r13 g13 b13",
  "		x2 y2 r2 g2 b2 x12 y12 r12 g12 b12 x32 y32 r32 g32 b32",
  "		x3 y3 r3 g3 b3 x32 y32 r32 g32 b32 x13 y13 r13 g13 b13",
  "		x32 y32 r32 g32 b32 x12 y12 r12 g12 b12 x13 y13 r13 g13 b13",
  "		ST ST ST ST",
  "	} {",
  "		x1 y1 x2 y2 x3 y3 r1 g1 b1 T",
  "	} ifelse",
  "} bind def",
  "\n",
	NULL
};


static char *gouraudtriangleEPS[] =
{
  "/bd{bind def}bind def /triangle { aload pop   setrgbcolor  aload pop 5 3",
  "roll 4 2 roll 3 2 roll exch moveto lineto lineto closepath fill } bd",
  "/computediff1 { 2 copy sub abs threshold ge {pop pop pop true} { exch 2",
  "index sub abs threshold ge { pop pop true} { sub abs threshold ge } ifelse",
  "} ifelse } bd /computediff3 { 3 copy 0 get 3 1 roll 0 get 3 1 roll 0 get",
  "computediff1 {true} { 3 copy 1 get 3 1 roll 1 get 3 1 roll 1 get",
  "computediff1 {true} { 3 copy 2 get 3 1 roll  2 get 3 1 roll 2 get",
  "computediff1 } ifelse } ifelse } bd /middlecolor { aload pop 4 -1 roll",
  "aload pop 4 -1 roll add 2 div 5 1 roll 3 -1 roll add 2 div 3 1 roll add 2",
  "div 3 1 roll exch 3 array astore } bd /gouraudtriangle { computediff3 { 4",
  "-1 roll aload 7 1 roll 6 -1 roll pop 3 -1 roll pop add 2 div 3 1 roll add",
  "2 div exch 3 -1 roll aload 7 1 roll exch pop 4 -1 roll pop add 2 div 3 1",
  "roll add 2 div exch 3 -1 roll aload 7 1 roll pop 3 -1 roll pop add 2 div 3",
  "1 roll add 2 div exch 7 3 roll 10 -3 roll dup 3 index middlecolor 4 1 roll",
  "2 copy middlecolor 4 1 roll 3 copy pop middlecolor 4 1 roll 13 -1 roll",
  "aload pop 17 index 6 index 15 index 19 index 6 index 17 index 6 array",
  "astore 10 index 10 index 14 index gouraudtriangle 17 index 5 index 17",
  "index 19 index 5 index 19 index 6 array astore 10 index 9 index 13 index",
  "gouraudtriangle 13 index 16 index 5 index 15 index 18 index 5 index 6",
  "array astore 12 index 12 index 9 index gouraudtriangle 17 index 16 index",
  "15 index 19 index 18 index 17 index 6 array astore 10 index 12 index 14",
  "index gouraudtriangle 18 {pop} repeat } { aload pop 5 3 roll aload pop 7 3",
  "roll aload pop 9 3 roll 8 index 6 index 4 index add add 3 div 10 1 roll 7",
  "index 5 index 3 index add add 3 div 10 1 roll 6 index 4 index 2 index add",
  "add 3 div 10 1 roll 9 {pop} repeat 3 array astore triangle } ifelse } bd",
  NULL};


#endif // _PS_RENDERER_

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Pierre Alliez

France France
No Biography provided

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 10 Jun 2003
Article Copyright 2001 by Pierre Alliez
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid