Re: polygon outlines

New Message Reply Date view Thread view Subject view Author view

Michael Jones (mtj++at++babar)
Tue, 22 Nov 1994 17:29:31 -0800


On Nov 22, 11:08pm, Kevin Russo wrote:
> Subject: polygon outlines
:Is there a way in Performer (1.2) to draw co-planar geometry,
:such as grid lines over a terrain or lat/lon over a sphere?
:
:I'm familiar with the decal algorithm, but since my grid line
:"decal" geometry is shared among multiple non-coplanar polygons,
:it doesn't give the correct effect everywhere. Does pfDecal do
:the right thing?
:
:Alternatively, I've tried outlining the polygons using the GL
:polymode(PYM_HOLLOW) in my draw node callback, but that doesn't
:seem to work on my Indigo2/Extreme, although I may be doing
:something wrong.
:
:I even tried implementing Kurt Akeley's "Z-buffer Charms" for outlined
:polygons and hidden lines, but it's got a lot of mode changes, and
:only seems to work if you draw each polygon one-at-a-time, rather than
:all the geometry at once.
:
:Thanks for any help you can give. Hopefully I'm missing something obvious.
:
:- Kevin
:
:--
:Kevin Russo
:US Naval Research Lab
:Washington, DC
>-- End of excerpt from Kevin Russo

Funny you should ask. I just did this yesterday morning. Here's the source
code that will appear as "libpfutil/style.c" in the next release of IRIS
Performer, along with the header file that is needed as well. This code
draws the whole scene in the indicated mode, but if you take a look you'll
see how the different methods work.

The idea is to call the pre-draw function just before pfDraw and the post-
darw function just afterwards. There's an example of this at the bottom of
the file.

By the way, you'll note that the code is set up for both IrisGL and OpenGL
compilation. If you have not yet looked at OpenGL, notice that it's not
really very different in spirit in most cases. I'm not going to extract
the OpenGL parts here for fear that I'll make a mistake. Take them out
yourself or just #ifdef IRISGL.

If you put this into your perfly, I suggest that you make the "w" key
cycle between the different modes.

**** style.c ****

/*
 * Copyright (c) 1994 Silicon Graphics, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that (i) the above copyright notices and this
 * permission notice appear in all copies of the software and related
 * documentation, and (ii) the name of Silicon Graphics may not be
 * used in any advertising or publicity relating to the software
 * without the specific, prior written permission of Silicon Graphics.
 *
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL,
 * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
 * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
 * THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <Performer/pf.h>
#include "pfutil.h"

/***
 *** Utility to produce fancy drawing styles (such has wire-frame
 *** with hidden lines removed) in IRIS Performer applications.
 ***/

/*
 * flatWhiteOn -- force white color and push Performer state
 */
static void
flatWhiteOn (void)
{
    static pfMaterial *white = NULL;

    if (white == NULL)
    {
        /*
         * NOTE: this is a known but slight memory wastage in
         * that the white material is never deallocated.
         */
        white = pfNewMtl(pfGetSharedArena());
        pfMtlColor(white, PFMTL_AMBIENT, 0.0f, 0.0f, 0.0f);
        pfMtlColor(white, PFMTL_DIFFUSE, 0.0f, 0.0f, 0.0f);
        pfMtlColor(white, PFMTL_SPECULAR, 0.0f, 0.0f, 0.0f);
        pfMtlColor(white, PFMTL_EMISSION, 1.0f, 1.0f, 1.0f);
        pfMtlSide(white, PFMTL_FRONT);
        pfMtlAlpha(white, 1.0f);
        pfMtlColorMode(white, PFMTL_FRONT, PFMTL_CMODE_COLOR);
    }

    /* save original graphics state */
    pfPushState();

    /* apply flat-white material for outlining */
    pfOverride(PFSTATE_ENLIGHTING | PFSTATE_FRONTMTL, PF_OFF);
    pfEnable(PFEN_LIGHTING);
    pfDisable(PFEN_TEXTURE);
    pfApplyMtl(white);

    /* prevent further changes to lighting, material, and texture */
    pfOverride(
        PFSTATE_ENLIGHTING |
        PFSTATE_FRONTMTL |
        PFSTATE_ENTEXTURE, PF_ON);
}

/*
 * flatWhiteOff -- remove white color and pop Performer state
 */
static void
flatWhiteOff (void)
{
    /* reenable changes to lighting, material, and texture */
    pfOverride(
        PFSTATE_ENLIGHTING |
        PFSTATE_FRONTMTL |
        PFSTATE_ENTEXTURE, PF_OFF);

    /* restore original graphics state */
    pfPopState();
}

/*
 * pfuPreDrawStyle -- call just before pfDraw to obtain one of
 * several special draw styles. Also call pfuPostDrawStyle
 * after calling pfDraw if you use this function.
 */
void
pfuPreDrawStyle (int style)
{
    /* handle draw style */
    switch (style)
    {
    case PFUSTYLE_POINTS:
        flatWhiteOn();
        pfCullFace(PFCF_OFF);
#ifdef IRISGL
        polymode(PYM_POINT);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
#endif
        break;

    case PFUSTYLE_LINES:
        flatWhiteOn();
        pfCullFace(PFCF_OFF);
#ifdef IRISGL
        polymode(PYM_LINE);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
#endif
        break;

    case PFUSTYLE_DASHED:
        flatWhiteOn();
        pfCullFace(PFCF_FRONT);
#ifdef IRISGL
        polymode(PYM_LINE);
        deflinestyle(1, 0x8888);
        setlinestyle(1);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glLineStipple(1, 0x8888);
        glEnable(GL_LINE_STIPPLE);
#endif
        pfDraw();
        pfCullFace(PFCF_BACK);
#ifdef IRISGL
        setlinestyle(0);
#else /* OPENGL */
        glDisable(GL_LINE_STIPPLE);
#endif
        break;

    case PFUSTYLE_HALOED:
        flatWhiteOn();
        pfCullFace(PFCF_OFF);
#ifdef IRISGL
        polymode(PYM_LINE);
        RGBwritemask(0, 0, 0);
        linewidth(5);
        displacepolygon(2.0f);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
        glLineWidth(5.0f);
        glPolygonOffsetEXT(2.0f, 0.0f);
#endif
        pfDraw();
#ifdef IRISGL
        RGBwritemask(0xff, 0xff, 0xff);
        linewidth(1);
        displacepolygon(0.0);
#else /* OPENGL */
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glLineWidth(1.0f);
        glPolygonOffsetEXT(0.0f, 0.0f);
#endif
        break;

    case PFUSTYLE_HIDDEN:
        flatWhiteOn();
        pfCullFace(PFCF_OFF);
#ifdef IRISGL
        RGBwritemask(0, 0, 0);
        displacepolygon(2.0);
#else /* OPENGL */
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
        glPolygonOffsetEXT(2.0f, 0.0f);
#endif
        pfDraw();
#ifdef IRISGL
        polymode(PYM_LINE);
        RGBwritemask(0xff, 0xff, 0xff);
        displacepolygon(0.0);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
        glPolygonOffsetEXT(0.0f, 0.0f);
#endif
        break;

    case PFUSTYLE_FILLED:
        break;

    case PFUSTYLE_SCRIBED:
#ifdef IRISGL
        displacepolygon(2.0);
#else /* OPENGL */
        glPolygonOffsetEXT(2.0f, 0.0f);
#endif
        pfDraw();
        flatWhiteOn();
#ifdef IRISGL
        polymode(PYM_LINE);
        displacepolygon(0.0);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glPolygonOffsetEXT(0.0f, 0.0f);
#endif
        break;

    default:
        pfNotify(PFNFY_NOTICE, PFNFY_PRINT,
            "pfuPreDrawStyle: unknown draw style");
    }
}

/*
 * pfuPostDrawStyle -- call just after pfDraw to obtain one of
 * several special draw styles. You must have also called
 * pfuPreDrawStyle before calling pfDraw if you use this
 * function.
 */
void
pfuPostDrawStyle (int style)
{
    /* handle draw style */
    switch (style)
    {
    case PFUSTYLE_POINTS:
        flatWhiteOff();
#ifdef IRISGL
        polymode(PYM_FILL);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
        break;

    case PFUSTYLE_LINES:
        flatWhiteOff();
#ifdef IRISGL
        polymode(PYM_FILL);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
        break;

    case PFUSTYLE_DASHED:
        flatWhiteOff();
#ifdef IRISGL
        polymode(PYM_FILL);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
        break;

    case PFUSTYLE_HALOED:
        flatWhiteOff();
#ifdef IRISGL
        polymode(PYM_FILL);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
        break;

    case PFUSTYLE_HIDDEN:
        flatWhiteOff();
#ifdef IRISGL
        polymode(PYM_FILL);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
        break;

    case PFUSTYLE_FILLED:
        break;

    case PFUSTYLE_SCRIBED:
        flatWhiteOff();
#ifdef IRISGL
        polymode(PYM_FILL);
#else /* OPENGL */
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
        break;

    default:
        pfNotify(PFNFY_NOTICE, PFNFY_PRINT,
            "pfuPostDrawStyle: unknown draw style");
    }
}

**** here's the extract from pfutil.h that you'll need ****

        /*------------------------ pfuStyle ---------------------------*/

#define PFUSTYLE_POINTS 0
#define PFUSTYLE_LINES 1
#define PFUSTYLE_DASHED 2
#define PFUSTYLE_HALOED 3
#define PFUSTYLE_HIDDEN 4
#define PFUSTYLE_FILLED 5
#define PFUSTYLE_SCRIBED 6
#define PFUSTYLE_COUNT 7

void pfuPreDrawStyle(int style);
void pfuPostDrawStyle(int style);

**** and here's an example from perfly.c in the draw callback ****

/* convey draw style from localPreDraw to localPostDraw */
static int selectedDrawStyle = 0;

void
localPreDraw(pfChannel *chan, void *data)
{
  :
  :
    /*
     * remember draw style in case it changes between now
     * and the time localPostDraw() gets called.
     */
    selectedDrawStyle = ViewState->drawStyle;

    /* handle draw style */
    pfuPreDrawStyle(selectedDrawStyle);
}

void
localPostDraw(pfChannel *chan, void *data)
{
    /* handle draw style */
    pfuPostDrawStyle(selectedDrawStyle);
  :
  :
}

-- 

Be seeing you, Phone:415.390.1455 Fax:415.390.2658 M/S:8U-590 Michael T. Jones Silicon Graphics, Advanced Graphics Division mtj++at++sgi.com 2011 N. Shoreline Blvd., Mtn. View, CA 94039-7311


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:50:41 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.