[info-performer] Background Images, pfTextures vs pfdImages, conclusion

Date view Thread view Subject view Author view

From: Dan Johnston (dan.johnston++at++nrc.gc.ca)
Date: 09/01/2005 07:47:43


Thanks to the help of this group
(esp alexander.lechner++at++vertigo-systems.de)
I was able to draw an image background into
any pfChannel display. The image is now
a standard pfTexture applied to a quad the
size of my display window.

Below is the three code functions needed for
this. If an image background is provided for the
channel, then it will call the apChannelInitImage
routine to read the texture (or supply a default).
(PS I will fix the memory allocation for the
default image now that the code works.)

Then the pre-draw callback function will also
check for the existance of a background image
and draw it if it exists, or simply clear the
display to the (user supplied or default) background
color. I can set a shared memory flag that will
disable the display of the image even when one
exists.

If you want to display the background image
you call the third routine to create the quad
in the background and paste the texture.

Thanks again to all!

PS Alex. Please note I had to remove a call
to glDisable(GL_DEPTH_TEST) from your
code.

/*
 *---------------------------------------------------------------------------
 * apChannelInitImage
 *---------------------------------------------------------------------------
 */
/**
    \ingroup mod_library_channel
    A function that will initialize a pfAPC channel for image background.
    \param channel a pointer to the pfAPC channel structure to initialize
    \param setup a pointer to the pfAPC base structure where we store the
    arena value
*/
PFAPCDLLEXPORT void
apChannelInitImage( APchannel *channel, APsetup *setup )
{
    static uint *defaultImage;
    int i;

    /* Set up image texture */
    channel->imageData = pfNewTex( setup->arena );
    if( pfLoadTexFile(channel->imageData, channel->backgroundImage ) )
    {
     /* load was OK */
     pfNotify(PFNFY_DEBUG, PFNFY_PRINT,
          "apChannelInitImage() loaded image file %s!\n",
          channel->backgroundImage);
    }
    else
    {
     /* if the image file loading failed, define a default
      * pattern as a background image instead
      */
     pfNotify(PFNFY_DEBUG, PFNFY_PRINT,
     "apChannelInitImage() Could not load %s, using default image!\n",
         channel->backgroundImage);

     /* a simple texture image */
     defaultImage = (uint *)pfMalloc(sizeof(uint)*16*3,
   setup->arena );
 for( i=0; i < 16; i++ )
 {
     *(defaultImage++) = 0x00;
     *(defaultImage++) = 0xFF;
     *(defaultImage++) = 0x00;
 }
 pfTexImage( channel->imageData, defaultImage, 3, 4, 4, 1 );
    }
    /* create texture environment and GeoState for texturing the background */
    channel->imageDataGState = pfNewGState( setup->arena );
    channel->imageDataTexEnv = pfNewTEnv( setup->arena );

    pfGStateAttr( channel->imageDataGState, PFSTATE_TEXTURE,
      channel->imageData);
    pfGStateMode( channel->imageDataGState, PFSTATE_ENTEXTURE, PF_ON );
    pfGStateMode( channel->imageDataGState, PFSTATE_ENLIGHTING, PF_OFF );
    pfGStateAttr( channel->imageDataGState, PFSTATE_TEXENV,
      channel->imageDataTexEnv);

    /* since we have an image, default display of background is now image */
    setup->shared->background = PF_ON;
}

/*
 *---------------------------------------------------------------------------
 * localPreDraw
 *---------------------------------------------------------------------------
 */
/**
    \ingroup mod_library_channel
    ...we collected the common code into this local function. This code
    will be called before pfDraw.
    \param channel a pointer to the Performer pfChannel that is drawing
    \param data the pointer to the data passed to the channel when
    it was created (so that we can access the display setup structure)
*/
static void
localPreDraw (pfChannel *channel, void *data)
{
    ChanPassData *pass;
    APsetup *set;
    APchannel * apChan;

    pass = (ChanPassData *)data;
    set = pass->setup;
    apChan = pass->apchannel;

    /* check if there is a user supplier pre-draw callback */
    if( set->preDrawCB != NULL )
        set->preDrawCB( set );

    /* skip internal operation if flag set */
    if( set->skipDrawCB == PF_ON )
    {
     /* we still need to do the drawing */
 pfDraw();
 /* return from this callback without any more work */
 return;
    }

    if( apChan->backgroundImage != NULL && set->shared->background == PF_ON )
        DrawBackgroundImage( channel, data );
    else
        /* erase framebuffer and draw Earth-Sky model */
        pfClearChan(channel);

    /* enable/disable display of textures in models */
    if ( set->shared->texture == FALSE)
.... (many lines of code removed)
}

/*
 *---------------------------------------------------------------------------
 * DrawBackgroundImage
 *---------------------------------------------------------------------------
 */
/**
    \ingroup mod_library_channel
    The draw function for all pfChannel to place the background image
    on the back of the objects.
    \param channel a pointer to the Performer pfChannel that is drawing
    \param data the pointer to the data passed to the channel when
    it was created (so that we can access the display setup structure)
*/
PFAPCDLLEXPORT void
DrawBackgroundImage (pfChannel *channel, void *data)
{
    ChanPassData *pass;
    APchannel * apChan;
    static int justOnce = 0;
    int xsize, ysize;

    pass = (ChanPassData *)data;
    apChan = pass->apchannel;

    pfGetChanSize( channel, &xsize, &ysize );
    if (justOnce == 0)
    {
     pfNotify(PFNFY_DEBUG, PFNFY_PRINT,
         "preDraw, channel size is %d %d!\n",xsize,ysize);
     justOnce = 1;
    }

    /* we need to get our background texture and draw it */
    pfPushState();
    pfBasicState();

    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0,xsize,0,ysize, -1.0, 1.0);

    /* just draw a quad (rect plane) over all the background, texture it */
    pfApplyGState( apChan->imageDataGState );
    glBegin( GL_QUADS );
    glTexCoord2i( 0, 0 ); glVertex2i( 0, 0 );
    glTexCoord2i( 1, 0 ); glVertex2i( xsize, 0 );
    glTexCoord2i( 1, 1 ); glVertex2i( xsize, ysize );
    glTexCoord2i( 0, 1 ); glVertex2i( 0, ysize );
    glEnd();

    /* make sure the depth buffer is also cleared */
    glClear( GL_DEPTH_BUFFER_BIT );

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glDepthRange(0.0,1.0);
    glDepthFunc(GL_LEQUAL);

    pfPopState();
}

--
      ___|__    |
      /  |  \   ||\      Daniel (Dan) Johnston
     /___|___\  || \     Dan.Johnston++at++nrc.gc.ca
    _____|____  ||  \    National Research Council of Canada, London, ON
    |    |    | ||   \   Integrated Manufacturing Technologies Institute
\___|    |    | ||____\  Tel: (519) 430-7081   Fax: (519) 430-7140
 \_o_\___|____|_|______\_    Inst: http://www.nrc.gc.ca/imti
  \                o /    These opinions are my own! Not those of NRC.
   \________________/    Virtual Reality:
                        http://imti.nrc.gc.ca/vetc_e/vetc_e.html
 More Tall Ships - Fewer Computers!


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Thu Sep 01 2005 - 07:50:21 PDT