Re: How to build the senario of submarine

New Message Reply Date view Thread view Subject view Author view

Scott McMillan (scott++at++ht.com)
Thu, 28 Aug 1997 13:49:51 -0400 (EDT)


----- Forwarded message from Rob Jenkins -----

On Aug 27, 7:47pm, jim wrote:
> Subject: How to build the senario of submarine
> Hi:
> Have you any ideas about submarine simulation. I'd like to render the
> circle channel of telescope and the undersea senario.
>

If your quesion is how to achieve the circular 'window' then you could do that
with a stencil mask, you draw a circle to the stencil planes, enable a stencil
test such that anything then drawn outside the circle fails the stencil test. I
think there's OpenGL examples, you could put the OpenGL in a predraw call back
then draw the scene, I dare say someone on the list has done something similar
already.

Cheers
Rob

----- End of forwarded message from Rob Jenkins -----

Gee, could Rob be talking about me? ;-)

Actually the original thread began back in January with Angus Dorbie's post
(Re: pfPipeWindows & Texture on iR). And since then I have been fiddling
with it. Here's all the info I can give about using stencil planes to do
this.

1) use OpenGL

2) Add a stencil_flag variable to the shared arena

3) Get a visual that supports stencils. I do this after the call to
pfPipeWindow::config() and before pfPipeWindow::open()

   pw->config();

   //-------------------------------------------------------------------
   // Visuals testing code
   int constraints[] = {PFFB_DOUBLEBUFFER,
                        PFFB_USE_GL,
                        PFFB_RGBA,
                        PFFB_DEPTH_SIZE, 24,
                        PFFB_STENCIL_SIZE, 2,
                        PFFB_RED_SIZE, 5,
                        PFFB_ALPHA_SIZE, 0,
                        NULL};

   pfFBConfig vis=pfuChooseFBConfig(NULL,-1,constraints,pfGetSharedArena());

   // if a visual is available that meets these constratints configure it.
   if (vis)
   {
      cerr << "pfuChooseFBConfig returned ID: " << hex << vis->visualid
           << endl;
      pw->setFBConfigId(vis->visualid);
   }
   pw->open();

   //pfuPrintPWinFBConfig(pw, NULL);

   // find out which visual I have and whether or not it supports stencils
   int vid = pw->getFBConfigId();

   int dst;
   int num = pw->query(PFQWIN_STENCIL_BITS, &dst);
   cerr << "Number of Stencil bits available = " << dst << endl;
   if (dst > 0)
      G_shared->stencil_flag = TRUE;
   else
      G_shared->stencil_flag = FALSE;

A few notes: (1) you may have to fiddle with the constraints array as you go
from platform to platform; (2) be careful not to request the 23depth/1stencil
mode on the RE's and IR's because a clear of the depth buffer will also
destroy any stencil information (thanks Sharon) -- thats why I have requested
two stencil bits even though only one is needed in my application.

4) You need to build the stencil mask in the DRAW process so I do the
following at the beginning of my draw callback:

   static int first_time = TRUE;

   // ======= FIRST TIME INIT =======
   if (first_time)
   {
      if (G_shared->stencil_flag)
      {
         StencilHUD(scope_chan->getPWin());
      }
      first_time = FALSE;
   }

This uses the StencilHUD function from Angus Dorbie:

static void StencilHUD(pfPipeWindow *pw)
{
   double f;
   static int mapped = 0;
   float new_x = 0.0f, new_y = 0.0f;

   pw->select(); //pfSelectPWin(pw);

   glPushMatrix();
   glLoadIdentity();
   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();
   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
   glMatrixMode(GL_MODELVIEW);

   glDisable(GL_CULL_FACE);
   glDisable(GL_DEPTH_TEST);
   glEnable(GL_STENCIL_TEST);

   glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);

   glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
   glClear(GL_COLOR_BUFFER_BIT);
   glColor3f(0.0f, 0.0f, 0.0f);

   /* Clear stencil planes to one over entire window */
   glClearStencil(0);
   glClear(GL_STENCIL_BUFFER_BIT);
   /* were a drawin' */
   glStencilFunc(GL_ALWAYS, 0x1, 0x1);
   glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

   glBegin(GL_TRIANGLE_FAN);
   for(f = 0.0; f< 359.5; f+=1.0)
   {
      pfSinCos((float)f, &new_x, &new_y);
      glVertex2f(new_x, new_y);
   }
   glEnd();

   glEnable(GL_CULL_FACE);
   glEnable(GL_DEPTH_TEST);

   // reset framebuffer
   glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
   glClear(GL_COLOR_BUFFER_BIT);

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

   glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
}

Note that this sets up the projection so that 0,0 is in the middle of the
channel (or is it pipewindow?) and a circle is drawn with radius 1 centered
at 0,0 which takes it to the edges of the channel.

Also note I have only gotten this to work in full screen applications. I
have started trying to do this in smaller window that I can move around with
little luck yet. I am pretty sure that if you begin moving the window around
you need to rebuild the stencil plane each time. Not sure about resizing
yet.

5) You must enable the stencil test in the DRAW callback as follows:

   // enable stencil test
   if (G_shared->stencil_flag)
   {
      glStencilFunc(GL_EQUAL, 0x1, 0x1);
      glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
      glEnable(GL_STENCIL_TEST);
   }

   // ========= DRAW =========
   // invoke Performer draw-processing for this frame
   pfDraw();

   // disable stencil test
   if (G_shared->stencil_flag)
   {
      glDisable(GL_STENCIL_TEST);
   }

6) If you don't get a visual with stencil bits then you have to resort to
using OpenGL commands in post-DRAW to draw black polygons around the outside
of your view. I can use the same orthographic projection as in StencilHUD,
to do this.

void drawScopeTemplate()
{
   float x,y;
   const int NUM_SIDES = 48;

   glColor3ub(0,0,0);
   glBegin(GL_TRIANGLE_STRIP);
   for (int j=0; j<NUM_SIDES; j++)
   {
      pfSinCos(((float) j)*360.0/((float) (NUM_SIDES - 1)), &x, &y);
      glVertex2f(x*1.414, y*1.414);
      glVertex2f(x, y);
   }
   glEnd();
}

-- 
  Scott McMillan  |    HT Medical, Inc.   | Developing medical VE's
   scott++at++ht.com   |   http://www.ht.com   | surgical simulations
 Ph: 301-984-3706 |6001 Montrose Rd., #902| and surgery simulation
Fax: 301-984-2104 |  Rockville, MD 20852  | creation tools.

======================================================================= List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/ Submissions: info-performer++at++sgi.com Admin. requests: info-performer-request++at++sgi.com


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:55:50 PDT

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