Skip to content
Snippets Groups Projects
Commit 00418abb authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

better solution for offset
parent a9b14a1d
Branches
Tags
No related merge requests found
/* $Id: gl2ps.cpp,v 1.90 2004-11-22 08:10:29 geuzaine Exp $ */ /* $Id: gl2ps.cpp,v 1.91 2004-11-22 18:00:30 geuzaine Exp $ */
/* /*
* GL2PS, an OpenGL to PostScript Printing Library * GL2PS, an OpenGL to PostScript Printing Library
* Copyright (C) 1999-2004 Christophe Geuzaine <geuz@geuz.org> * Copyright (C) 1999-2004 Christophe Geuzaine <geuz@geuz.org>
...@@ -62,9 +62,14 @@ ...@@ -62,9 +62,14 @@
* *
*********************************************************************/ *********************************************************************/
/* Magic numbers */ /* Magic numbers (assuming that the order of magnitude of window
coordinates is 10^3) */
#define GL2PS_ZERO(arg) (fabs(arg) < 1.e-20) #define GL2PS_EPSILON 5.0e-3F
#define GL2PS_ZSCALE 1000.0F
#define GL2PS_ZOFFSET 1.0F
#define GL2PS_ZOFFSET_LARGE 20.0F
#define GL2PS_ZERO(arg) (fabs(arg) < 1.e-20)
/* Primitive types */ /* Primitive types */
...@@ -188,7 +193,7 @@ typedef struct { ...@@ -188,7 +193,7 @@ typedef struct {
GLint format, sort, options, colorsize, colormode, buffersize; GLint format, sort, options, colorsize, colormode, buffersize;
char *title, *producer, *filename; char *title, *producer, *filename;
GLboolean boundary, blending; GLboolean boundary, blending;
GLfloat epsilon, *feedback, offset[2], lastlinewidth; GLfloat *feedback, offset[2], lastlinewidth;
GLint viewport[4], blendfunc[2]; GLint viewport[4], blendfunc[2];
GL2PSrgba *colormap, lastrgba, threshold; GL2PSrgba *colormap, lastrgba, threshold;
GL2PSlist *primitives; GL2PSlist *primitives;
...@@ -926,15 +931,15 @@ static GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane) ...@@ -926,15 +931,15 @@ static GLint gl2psTestSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane)
else{ else{
for(i = 0; i < prim->numverts; i++){ for(i = 0; i < prim->numverts; i++){
j = gl2psGetIndex(i, prim->numverts); j = gl2psGetIndex(i, prim->numverts);
if(d[j] > gl2ps->epsilon){ if(d[j] > GL2PS_EPSILON){
if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF;
else if(type != GL2PS_IN_BACK_OF) return 1; else if(type != GL2PS_IN_BACK_OF) return 1;
if(d[i] < -gl2ps->epsilon) return 1; if(d[i] < -GL2PS_EPSILON) return 1;
} }
else if(d[j] < -gl2ps->epsilon){ else if(d[j] < -GL2PS_EPSILON){
if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF;
else if(type != GL2PS_IN_FRONT_OF) return 1; else if(type != GL2PS_IN_FRONT_OF) return 1;
if(d[i] > gl2ps->epsilon) return 1; if(d[i] > GL2PS_EPSILON) return 1;
} }
} }
} }
...@@ -956,27 +961,27 @@ static GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane, ...@@ -956,27 +961,27 @@ static GLint gl2psSplitPrimitive(GL2PSprimitive *prim, GL2PSplane plane,
switch(prim->type){ switch(prim->type){
case GL2PS_POINT : case GL2PS_POINT :
if(d[0] > gl2ps->epsilon) type = GL2PS_IN_BACK_OF; if(d[0] > GL2PS_EPSILON) type = GL2PS_IN_BACK_OF;
else if(d[0] < -gl2ps->epsilon) type = GL2PS_IN_FRONT_OF; else if(d[0] < -GL2PS_EPSILON) type = GL2PS_IN_FRONT_OF;
else type = GL2PS_COINCIDENT; else type = GL2PS_COINCIDENT;
break; break;
default : default :
for(i = 0; i < prim->numverts; i++){ for(i = 0; i < prim->numverts; i++){
j = gl2psGetIndex(i, prim->numverts); j = gl2psGetIndex(i, prim->numverts);
if(d[j] > gl2ps->epsilon){ if(d[j] > GL2PS_EPSILON){
if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF; if(type == GL2PS_COINCIDENT) type = GL2PS_IN_BACK_OF;
else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING; else if(type != GL2PS_IN_BACK_OF) type = GL2PS_SPANNING;
if(d[i] < -gl2ps->epsilon){ if(d[i] < -GL2PS_EPSILON){
gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(in0, in1, &in, i, j);
gl2psAddIndex(out0, out1, &out, i, j); gl2psAddIndex(out0, out1, &out, i, j);
type = GL2PS_SPANNING; type = GL2PS_SPANNING;
} }
gl2psAddIndex(out0, out1, &out, j, -1); gl2psAddIndex(out0, out1, &out, j, -1);
} }
else if(d[j] < -gl2ps->epsilon){ else if(d[j] < -GL2PS_EPSILON){
if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF; if(type == GL2PS_COINCIDENT) type = GL2PS_IN_FRONT_OF;
else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING; else if(type != GL2PS_IN_FRONT_OF) type = GL2PS_SPANNING;
if(d[i] > gl2ps->epsilon){ if(d[i] > GL2PS_EPSILON){
gl2psAddIndex(in0, in1, &in, i, j); gl2psAddIndex(in0, in1, &in, i, j);
gl2psAddIndex(out0, out1, &out, i, j); gl2psAddIndex(out0, out1, &out, i, j);
type = GL2PS_SPANNING; type = GL2PS_SPANNING;
...@@ -1276,12 +1281,12 @@ static void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsil ...@@ -1276,12 +1281,12 @@ static void gl2psTraverseBspTree(GL2PSbsptree *tree, GL2PSxyz eye, GLfloat epsil
} }
} }
static void gl2psSetPrecisionAndApplyOffsets() static void gl2psRescaleAndOffset()
{ {
GL2PSprimitive *prim; GL2PSprimitive *prim;
GLfloat minZ, maxZ, simple; GLfloat minZ, maxZ, rangeZ, scaleZ;
GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ; GLfloat factor, units, area, dZ, dZdX, dZdY, maxdZ;
int i, j, offset = 0; int i, j;
if(!gl2psListNbr(gl2ps->primitives)) if(!gl2psListNbr(gl2ps->primitives))
return; return;
...@@ -1289,7 +1294,6 @@ static void gl2psSetPrecisionAndApplyOffsets() ...@@ -1289,7 +1294,6 @@ static void gl2psSetPrecisionAndApplyOffsets()
/* get z-buffer range */ /* get z-buffer range */
prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, 0); prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, 0);
minZ = maxZ = prim->verts[0].xyz[2]; minZ = maxZ = prim->verts[0].xyz[2];
if(prim->offset) offset = 1;
for(i = 1; i < prim->numverts; i++){ for(i = 1; i < prim->numverts; i++){
if(prim->verts[i].xyz[2] < minZ) minZ = prim->verts[i].xyz[2]; if(prim->verts[i].xyz[2] < minZ) minZ = prim->verts[i].xyz[2];
if(prim->verts[i].xyz[2] > maxZ) maxZ = prim->verts[i].xyz[2]; if(prim->verts[i].xyz[2] > maxZ) maxZ = prim->verts[i].xyz[2];
...@@ -1300,59 +1304,54 @@ static void gl2psSetPrecisionAndApplyOffsets() ...@@ -1300,59 +1304,54 @@ static void gl2psSetPrecisionAndApplyOffsets()
if(prim->verts[j].xyz[2] < minZ) minZ = prim->verts[j].xyz[2]; if(prim->verts[j].xyz[2] < minZ) minZ = prim->verts[j].xyz[2];
if(prim->verts[j].xyz[2] > maxZ) maxZ = prim->verts[j].xyz[2]; if(prim->verts[j].xyz[2] > maxZ) maxZ = prim->verts[j].xyz[2];
} }
if(prim->offset) offset = 1;
} }
rangeZ = (maxZ - minZ);
/* set precision */ /* rescale z-buffer coordinate in [0,GL2PS_ZSCALE], to make it of
gl2ps->epsilon = (maxZ - minZ) / 5000.0F; the same order of magnitude as the x and y coordinates */
simple = (maxZ - minZ) / 1000.0F; scaleZ = GL2PS_ZERO(rangeZ) ? GL2PS_ZSCALE : GL2PS_ZSCALE / rangeZ;
if(GL2PS_ZERO(gl2ps->epsilon)) gl2ps->epsilon = 0.0002F;
if(GL2PS_ZERO(simple)) simple = 0.001F;
/* apply offsets */ /* apply offsets */
if(gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET){ for(i = 0; i < gl2psListNbr(gl2ps->primitives); i++){
for(i = 0; i < gl2psListNbr(gl2ps->primitives); i++){ prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i);
prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); for(j = 0; j < prim->numverts; j++){
if(prim->type == GL2PS_LINE){ prim->verts[j].xyz[2] *= scaleZ;
if(gl2ps->sort == GL2PS_SIMPLE_SORT){
prim->verts[0].xyz[2] -= simple * 20.0F;
prim->verts[1].xyz[2] -= simple * 20.0F;
}
else{
prim->verts[0].xyz[2] -= simple;
prim->verts[1].xyz[2] -= simple;
}
}
} }
} if((gl2ps->options & GL2PS_SIMPLE_LINE_OFFSET) &&
else if(offset){ /* at least one primitive needs to be offsetted */ (prim->type == GL2PS_LINE)){
factor = gl2ps->offset[0]; if(gl2ps->sort == GL2PS_SIMPLE_SORT){
units = gl2ps->offset[1]; prim->verts[0].xyz[2] -= GL2PS_ZOFFSET_LARGE;
for(i = 0; i < gl2psListNbr(gl2ps->primitives); i++){ prim->verts[1].xyz[2] -= GL2PS_ZOFFSET_LARGE;
prim = *(GL2PSprimitive**)gl2psListPointer(gl2ps->primitives, i); }
if(prim->offset && prim->type == GL2PS_TRIANGLE){ else{
area = prim->verts[0].xyz[2] -= GL2PS_ZOFFSET;
(prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) * prim->verts[1].xyz[2] -= GL2PS_ZOFFSET;
(prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) -
(prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
(prim->verts[1].xyz[1] - prim->verts[0].xyz[1]);
dZdX =
(prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
(prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
(prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
(prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) / area;
dZdY =
(prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
(prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
(prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
(prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) / area;
maxdZ = (GLfloat)sqrt(dZdX*dZdX + dZdY*dZdY);
dZ = factor * maxdZ + units;
prim->verts[0].xyz[2] += dZ;
prim->verts[1].xyz[2] += dZ;
prim->verts[2].xyz[2] += dZ;
} }
} }
else if(prim->offset && (prim->type == GL2PS_TRIANGLE)){
factor = gl2ps->offset[0];
units = gl2ps->offset[1];
area =
(prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
(prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) -
(prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
(prim->verts[1].xyz[1] - prim->verts[0].xyz[1]);
dZdX =
(prim->verts[2].xyz[1] - prim->verts[1].xyz[1]) *
(prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) -
(prim->verts[1].xyz[1] - prim->verts[0].xyz[1]) *
(prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) / area;
dZdY =
(prim->verts[1].xyz[0] - prim->verts[0].xyz[0]) *
(prim->verts[2].xyz[2] - prim->verts[1].xyz[2]) -
(prim->verts[2].xyz[0] - prim->verts[1].xyz[0]) *
(prim->verts[1].xyz[2] - prim->verts[0].xyz[2]) / area;
maxdZ = (GLfloat)sqrt(dZdX*dZdX + dZdY*dZdY);
dZ = factor * maxdZ + units;
prim->verts[0].xyz[2] += dZ;
prim->verts[1].xyz[2] += dZ;
prim->verts[2].xyz[2] += dZ;
}
} }
} }
...@@ -1370,7 +1369,7 @@ static GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane) ...@@ -1370,7 +1369,7 @@ static GLint gl2psGetPlaneFromPoints(GL2PSxyz a, GL2PSxyz b, GL2PSplane plane)
plane[1] = a[0] - b[0]; plane[1] = a[0] - b[0];
n = (GLfloat)sqrt(plane[0]*plane[0] + plane[1]*plane[1]); n = (GLfloat)sqrt(plane[0]*plane[0] + plane[1]*plane[1]);
plane[2] = 0.0F; plane[2] = 0.0F;
if(n != 0.0){ if(!GL2PS_ZERO(n)){
plane[0] /= n; plane[0] /= n;
plane[1] /= n; plane[1] /= n;
plane[3] = -plane[0]*a[0]-plane[1]*a[1]; plane[3] = -plane[0]*a[0]-plane[1]*a[1];
...@@ -1399,9 +1398,9 @@ static GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane) ...@@ -1399,9 +1398,9 @@ static GLint gl2psCheckPoint(GL2PSxyz point, GL2PSplane plane)
GLfloat pt_dis; GLfloat pt_dis;
pt_dis = gl2psComparePointPlane(point, plane); pt_dis = gl2psComparePointPlane(point, plane);
if(pt_dis > gl2ps->epsilon) return GL2PS_POINT_INFRONT; if(pt_dis > GL2PS_EPSILON) return GL2PS_POINT_INFRONT;
else if(pt_dis < -gl2ps->epsilon) return GL2PS_POINT_BACK; else if(pt_dis < -GL2PS_EPSILON) return GL2PS_POINT_BACK;
else return GL2PS_POINT_COINCIDENT; else return GL2PS_POINT_COINCIDENT;
} }
static void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim, static void gl2psAddPlanesInBspTreeImage(GL2PSprimitive *prim,
...@@ -4310,7 +4309,7 @@ static GLint gl2psPrintPrimitives(void) ...@@ -4310,7 +4309,7 @@ static GLint gl2psPrintPrimitives(void)
return GL2PS_NO_FEEDBACK; return GL2PS_NO_FEEDBACK;
} }
gl2psSetPrecisionAndApplyOffsets(); gl2psRescaleAndOffset();
switch(gl2ps->format){ switch(gl2ps->format){
case GL2PS_TEX : case GL2PS_TEX :
...@@ -4348,11 +4347,11 @@ static GLint gl2psPrintPrimitives(void) ...@@ -4348,11 +4347,11 @@ static GLint gl2psPrintPrimitives(void)
gl2psBuildBspTree(root, gl2ps->primitives); gl2psBuildBspTree(root, gl2ps->primitives);
if(GL_TRUE == gl2ps->boundary) gl2psBuildPolygonBoundary(root); if(GL_TRUE == gl2ps->boundary) gl2psBuildPolygonBoundary(root);
if(gl2ps->options & GL2PS_OCCLUSION_CULL){ if(gl2ps->options & GL2PS_OCCLUSION_CULL){
gl2psTraverseBspTree(root, eye, -gl2ps->epsilon, gl2psLess, gl2psTraverseBspTree(root, eye, -GL2PS_EPSILON, gl2psLess,
gl2psAddInImageTree, 1); gl2psAddInImageTree, 1);
gl2psFreeBspImageTree(&gl2ps->imagetree); gl2psFreeBspImageTree(&gl2ps->imagetree);
} }
gl2psTraverseBspTree(root, eye, gl2ps->epsilon, gl2psGreater, gl2psTraverseBspTree(root, eye, GL2PS_EPSILON, gl2psGreater,
pprim, 0); pprim, 0);
gl2psFreeBspTree(&root); gl2psFreeBspTree(&root);
/* reallocate the primitive list (it's been deleted by /* reallocate the primitive list (it's been deleted by
...@@ -4397,7 +4396,6 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer, ...@@ -4397,7 +4396,6 @@ GL2PSDLL_API GLint gl2psBeginPage(const char *title, const char *producer,
gl2ps->compress = NULL; gl2ps->compress = NULL;
gl2ps->imagemap_head = NULL; gl2ps->imagemap_head = NULL;
gl2ps->imagemap_tail = NULL; gl2ps->imagemap_tail = NULL;
gl2ps->epsilon = 0.0F; /* adjusted later according to z-buffer values */
if(gl2ps->options & GL2PS_USE_CURRENT_VIEWPORT){ if(gl2ps->options & GL2PS_USE_CURRENT_VIEWPORT){
glGetIntegerv(GL_VIEWPORT, gl2ps->viewport); glGetIntegerv(GL_VIEWPORT, gl2ps->viewport);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment